I'm trying to fix some errors according to JSLint and there are some errors I can't get rid of:
line 46 character 13
Missing 'new'.
SortPosts(categories[categoryNumber].textContent);
line 65 character 16
Unexpected '('.
if (typeof (Storage) !== "undefined") {
line 65 character 9Unexpected 'typeof'. Use '===' to compare directly with undefined.
if (typeof (Storage) !== "undefined") {
This is my code:
window.onload = function () {
"use strict";
var categories,
value,
i,
j,
article,
li,
postsAvailable = false;
function removeElementsByClass() {
var elements = document.getElementsByClassName("forumPost");
while (elements.length > 0) {
elements[0].parentNode.removeChild(elements[0]);
}
}
function addRow(input) {
article = document.createElement('article');
article.className = 'forumPost';
article.innerHTML = "<div id='imageDiv'><img src='" + input.avatar + "' alt='Avatar'id='imageHTML'/><div id='personDiv'> " + input.firstName + " " + input.lastName + " (" + input.age + ") </div><div id='workDiv'>" + input.work + " </div></div><div id='headerDiv'>" + input.firstName + " schreef om <div id='dateDiv'>" + input.date + "</div></div></br><div id='postDiv'>" + input.post + "</div></article>";
document.getElementById('content').appendChild(article);
}
function SortPosts(category) {
if (localStorage.getItem(category) === "") {
alert("No posts found!");
} else {
removeElementsByClass();
if (category !== "Algemeen") {
value = JSON.parse(localStorage.getItem(category));
for (i = 0; i < value.length; ++i) {
addRow(value[i]);
}
} else {
for (i = 0; i < localStorage.length; ++i) {
if (localStorage.getItem(localStorage.key(i)) !== "") {
value = JSON.parse(localStorage.getItem(localStorage.key(i)));
for (j = 0; j < value.length; ++j) {
addRow(value[j]);
}
}
}
}
}
}
function getPostSorter(categoryNumber) {
return function () {
SortPosts(categories[categoryNumber].textContent);
};
}
document.getElementById("newCategoryButton").onclick = function () {
var input = document.getElementById("newCategoryInput").value;
if (input !== "") {
if (localStorage.getItem(input) !== null) {
alert("Categorie bestaat al!");
} else {
li = document.createElement('li');
li.innerHTML = "<a href='#'>" + input + "</a></li>";
localStorage.setItem(input, "");
document.getElementById("categories").appendChild(li);
}
} else {
alert("Uw invoer mag niet leeg zijn!");
}
document.getElementById("newCategoryInput").value = "";
};
if (typeof (Storage) !== "undefined") {
for (i = 0; i < localStorage.length; ++i) {
if (localStorage.getItem(localStorage.key(i)) !== "") {
postsAvailable = true;
break;
}
}
if (postsAvailable === false) {
article = document.createElement('article');
article.className = 'infobox';
article.innerHTML = "<header><h2>Geen posts gevonden!</h2></header><section><p>Ga naar het forum toe om een onderwerp toe te voegen</p></section></article>";
document.getElementById('content').appendChild(article);
} else {
for (i = 0; i < localStorage.length; ++i) {
if (localStorage.getItem(localStorage.key(i)) !== "") {
value = JSON.parse(localStorage.getItem(localStorage.key(i)));
for (j = 0; j < value.length; ++j) {
addRow(value[j]);
}
}
}
}
for (i = 0; i < localStorage.length; ++i) {
li = document.createElement('li');
li.className = "category";
li.innerHTML = "<a href='#'>" + localStorage.key(i) + "</a></li>";
document.getElementById("categories").appendChild(li);
}
categories = document.getElementsByClassName("category");
for (i = 0; i < categories.length; ++i) {
categories[i].addEventListener("click", getPostSorter(i));
}
} else {
alert("Uw browser ondersteunt geen localStorage. Gebruik alstublieft een nieuwere browser zoals Google Chrome, Mozilla Firefox of > Internet Explorer 7");
}
};
Could anyone tell me why these are wrong and what I should do to fix them? I've googled some more information but I wasn't able to actually find anything helpful. I've tried adding "new" to the SortPosts but then it gave me the message Do not use 'new' for side effects.
Missing 'new'.
SortPosts(categories[categoryNumber].textContent);
Functions with names starting with capital letters are, by convention, constructor functions. Yours is not. Rename the function to sortPosts.
Unexpected '('.
if (typeof (Storage) !== "undefined") {
typeof is an operator, not a function.
Use typeof Storage not typeof (Storage).
line 65 character 9Unexpected 'typeof'. Use '===' to compare directly with undefined.
Don't use typeof. Use Storage !== undefined.
NB: JSLint is a very opinionated linter. It is possible for undefined to be overridden. I prefer the typeof approach.
To fix these issues, change line 45 to this:
newSortPosts(categories[categoryNumber].textContent);
Renaming SortPosts to newSortPosts in your code.
On line 65 you don't need to compare the typeof, rather you can just see if Storage is undefined:
if (Storage !== undefined) {
Just a note you when using typeof, you don't need parentheses as typeof is an operator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
Related
I have a nested FOR loop that iterates over an object, and updating variables or attributes based on conditions. The last 'IF' on this loop formats a date and updates the field accordingly. For some reason the final line causes the loop to iterate twice, therefore updating the 'formattedDate' variable twice (in the object, there is only one single element with the 'childTag' = 'date'. Any help is appreciated!
for (let i = 0; i < submitFormData.tabs.length; i++) {
for (let j = 0; j < submitFormData.tabs[i].elements.length; j++) {
if (submitFormData.tabs[i].elements[j].childTag == "project_name") {
projectName = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_store") {
locationStore = ' #' + submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_street") {
locationStreet = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_city") {
locationCity = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_state") {
locationState = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_zip") {
locationZip = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "date") {
if (submitFormData.tabs[i].elements[j].value != "") {
console.log(submitFormData)
date = (submitFormData.tabs[i].elements[j].value.substring(0, 10));
formattedDate = (date.substring(5, 11) + '-' + date.substring(0, 4));
console.log(formattedDate, 'formatted date')
submitFormData.tabs[i].elements[j].value = formattedDate;
}
}
}
}
Sample of Object
I see that in the loop you manipulate the list which you iterate over.
submitFormData.tabs[i].elements
It would be better to make a copy of it and iterate over it.
const newSubmitFormData = [...submitFormData.tabs[i].elements]
for (let j = 0; j < newSubmitFormData .length; j++) { /* your code */ }
I am moving elements using javascript and I need to create a logic for the combinations happening during the drag/drops
I'm trying to get details from the elements, a CSS like selector could be also good, but dunno if it is possible.. (like copy-selector in chrome dev tools)
document.onmouseup = function(e){
targetDest = e.target;
//console.log('targetDest: ', targetDest);
let
indexA = Array.from(targetCurr.parentNode.children).indexOf(targetCurr),
indexB = Array.from(targetDest.parentNode.children).indexOf(targetDest);
console.log(indexA, indexB);
if(targetDest != targetCurr){
if(targetDest == document.documentElement){
console.log('document');
}
else if(targetDest == undefined){
console.log('undefined');
}
else if(!targetDest){
console.log('!dest');
}
else if(targetDest == null){
console.log('null');
}
else if(targetDest == false){
console.log('false');
}
else{
console.log('else');
//targetCurr.parentNode.insertBefore(targetDest, targetCurr);
//console.log('...');
}
}else{
console.log('itself');
}
}
Keep in mind that this will not necessarily uniquely identify elements. But, you can construct that type of selector by traversing upwards from the node and prepending the element you're at. You could potentially do something like this
var generateQuerySelector = function(el) {
if (el.tagName.toLowerCase() == "html")
return "HTML";
var str = el.tagName;
str += (el.id != "") ? "#" + el.id : "";
if (el.className) {
var classes = el.className.split(/\s/);
for (var i = 0; i < classes.length; i++) {
str += "." + classes[i]
}
}
return generateQuerySelector(el.parentNode) + " > " + str;
}
var qStr = generateQuerySelector(document.querySelector("div.moo"));
alert(qStr);
body
<div class="outer">
div.outer
<div class="inner" id="foo">
div#foo.inner
<div class="moo man">
div.moo.man
</div>
</div>
</div>
I wouldn't suggest using this for much besides presenting the information to a user. Splitting it up and reusing parts are bound to cause problems.
My solution using :nth-child:
function getSelector(elm)
{
if (elm.tagName === "BODY") return "BODY";
const names = [];
while (elm.parentElement && elm.tagName !== "BODY") {
if (elm.id) {
names.unshift("#" + elm.getAttribute("id")); // getAttribute, because `elm.id` could also return a child element with name "id"
break; // Because ID should be unique, no more is needed. Remove the break, if you always want a full path.
} else {
let c = 1, e = elm;
for (; e.previousElementSibling; e = e.previousElementSibling, c++) ;
names.unshift(elm.tagName + ":nth-child(" + c + ")");
}
elm = elm.parentElement;
}
return names.join(">");
}
var qStr = getSelector(document.querySelector("div.moo"));
alert(qStr);
body
<div class="outer">
div.outer
<div class="inner" id="foo">
div#foo.inner
<div class="moo man">
div.moo.man
</div>
</div>
</div>
Please note it won't return the whole path if there's an element with ID in it - every ID should be unique on the page, as valid HTML requires.
I use output of this function in document.querySelector later in the code, because I needed to return focus to the same element after replaceChild of its parent element.
I hope CollinD won't mind I borrowed his markup for the code snippet :-)
I mixed the 2 solutions proposed to have a result readable by humans and which gives the right element if there are several similar siblings:
function elemToSelector(elem) {
const {
tagName,
id,
className,
parentNode
} = elem;
if (tagName === 'HTML') return 'HTML';
let str = tagName;
str += (id !== '') ? `#${id}` : '';
if (className) {
const classes = className.split(/\s/);
for (let i = 0; i < classes.length; i++) {
str += `.${classes[i]}`;
}
}
let childIndex = 1;
for (let e = elem; e.previousElementSibling; e = e.previousElementSibling) {
childIndex += 1;
}
str += `:nth-child(${childIndex})`;
return `${elemToSelector(parentNode)} > ${str}`;
}
Test with:
// Select an element in Elements tab of your navigator Devtools, or replace $0
document.querySelector(elemToSelector($0)) === $0 &&
document.querySelectorAll(elemToSelector($0)).length === 1
Which might give you something like, it's a bit longer but it's readable and it always works:
HTML > BODY:nth-child(2) > DIV.container:nth-child(2) > DIV.row:nth-child(2) > DIV.col-md-4:nth-child(2) > DIV.sidebar:nth-child(1) > DIV.sidebar-wrapper:nth-child(2) > DIV.my-4:nth-child(1) > H4:nth-child(3)
Edit: I just found the package unique-selector
Small improvement of the #CollinD answer :
1/ Return value when the selector is unique
2/ Trim classes value (classes with end blanks make errors)
3/ Split multiple spaces between classes
var getSelector = function(el) {
if (el.tagName.toLowerCase() == "html")
return "html";
var str = el.tagName.toLowerCase();
str += (el.id != "") ? "#" + el.id : "";
if (el.className) {
var classes = el.className.trim().split(/\s+/);
for (var i = 0; i < classes.length; i++) {
str += "." + classes[i]
}
}
if(document.querySelectorAll(str).length==1) return str;
return getSelector(el.parentNode) + " > " + str;
}
Based on previous solutions, I made a typescript solution with a shorter selector and additional checks.
function elemToSelector(elem: HTMLElement): string {
const {
tagName,
id,
className,
parentElement
} = elem;
let str = '';
if (id !== '' && id.match(/^[a-z].*/)) {
str += `#${id}`;
return str;
}
str = tagName;
if (className) {
str += '.' + className.replace(/(^\s)/gm, '').replace(/(\s{2,})/gm, ' ')
.split(/\s/).join('.');
}
const needNthPart = (el: HTMLElement): boolean => {
let sib = el.previousElementSibling;
if (!el.className) {
return true;
}
while (sib) {
if (el.className !== sib.className) {
return false;
}
sib = sib.previousElementSibling;
}
return false;
}
const getNthPart = (el: HTMLElement): string => {
let childIndex = 1;
let sib = el.previousElementSibling;
while (sib) {
childIndex++;
sib = sib.previousElementSibling;
}
return `:nth-child(${childIndex})`;
}
if (needNthPart(elem)) {
str += getNthPart(elem);
}
if (!parentElement) {
return str;
}
return `${elemToSelector(parentElement)} > ${str}`;
}
We encountered a problem with the minification provided by the NuGet package Microsoft.AspNet.Web.Optimization, as it seems to have problems with let. Somehow the minifier sets the name of the variables bookingDefaultIndex and i to the same name (i). This makes Firefox and IE 11 report a scope problem (Firefox reports SyntaxError: redeclaration of let i, IE 11 reports Let/Const redeclaration), because the variable was already defined. Without minification, the code works just fine in IE and FF. Chrome reports no problems with the minified code.
In the following code snippets, I marked the relevant lines with a comment that starts with // [SO-COMMENT], so you can search for that to see the problematic lines.
This is the unminified function that causes problems:
_handleDDLValuesByContext: function () {
if (this.options.isCreate) {
if (this.options.isChildCreation) {
//If we are creating a child ->
this.$ddlBookingType.val(this.options.data.BookingTypeID);
this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID);
this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID);
if (this.options.data.ServiceCategoryID == null) {
this.$ddlServiceCategory.val('-1').trigger('change');
if (this.options.data.PricePerUnit != null) {
this.$structureRate.val(GetFormat(this.options.data.PricePerUnit));
}
} else {
this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger('change');
}
//If we are creating a child, prefill his accounting type with the parent accounting type
if (this.options.data.AccountingTypeID == null) {
this.$ddlAccountingType.val('-1').trigger('change');
} else {
this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger('change');
}
} else {
//If it's parent creation ->
let bookingTypes = this.options.structureSpecificData.BookingTypes;
let bookingDefaultID = null;
// [SO-COMMENT] the following variable is minified to 'i'
let bookingDefaultIndex = null;
for (let i = 0, len = bookingTypes.length; i < len; i++) {
if (bookingTypes[i].IsDefault) {
bookingDefaultID = bookingTypes[i].ID;
bookingDefaultIndex = i;
}
}
let allocationTypes = this.options.structureSpecificData.AllocationUnitTypes;
if (bookingDefaultID == null) {
//In case there's no default booking type id, we set the booking types, allocations and effort allocations to their first available value
this.$ddlBookingType.val(bookingTypes[0].ID);
this.$ddlAllocationUnit.val(allocationTypes[0].ID);
this.$ddlEffortAllocationUnit.val(allocationTypes[0].ID);
} else {
let allocationDefaultID = null;
this.$ddlBookingType.val(bookingDefaultID).trigger('change');
allocationTypes = [];
let bookings = this.options.structureSpecificData.BookingTypes;
let allocations = this.options.structureSpecificData.AllocationUnitTypes;
// [SO-COMMENT] this is the 'original' i
for (let i = 0, len = allocations.length; i < len; i++) {
if (allocations[i].BaseUnitID == bookings[bookingDefaultIndex].BaseUnitID) {
allocationTypes.push(allocations[i]);
}
}
for (let i = 0, len = allocationTypes.length; i < len; i++) {
if (allocationTypes[i].IsDefault) {
allocationDefaultID = allocationTypes[i].ID;
}
}
if (allocationDefaultID == null) {
this.$ddlAllocationUnit.val(allocationTypes[0].ID);
this.$ddlEffortAllocationUnit.val(allocationTypes[0].ID);
} else {
this.$ddlAllocationUnit.val(allocationDefaultID);
this.$ddlEffortAllocationUnit.val(allocationDefaultID);
}
}
this.$ddlServiceCategory.val('-1');
}
} else {
//If we are edditing ->
this.$ddlBookingType.val(this.options.data.BookingTypeID);
this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID);
this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID);
if (this.options.data.IsParentElement) {
this.$ddlServiceCategory.val('-1').trigger('change');
//We have to check against a NaN type since the effort and the total cost can be of that type
//in case we have a structure hierarchy with an accounting type of fixed price and therefore no effort and cost
if (isNaN(this.options.structureTotalCost)) {
this.$structureTotalCost.val('');
} else {
this.$structureTotalCost.val(GetFormat(this.options.structureTotalCost));
}
if (isNaN(this.options.structureEffort)) {
this.$structureEffortUnits.val('');
} else {
this.$structureEffortUnits.val(GetFormat(this.options.structureEffort));
}
} else {
if (this.options.data.ServiceCategoryID == null) {
this.$ddlServiceCategory.val('-1').trigger('change');
if (this.options.data.PricePerUnit != null) {
this.$structureRate.val(GetFormat(this.options.data.PricePerUnit));
this._checkTotalCostCalculation();
}
} else {
if (this.options.data.PricePerUnit !== null) {
this.$structureRate.val(GetFormat(this.options.data.PricePerUnit));
this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID);
this._checkTotalCostCalculation();
} else {
this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger('change');
}
}
}
//Since we are editing we should prefill the accounting type with the accounting id and the fixed price too if it exists
//And not trigger anything
if (this.options.data.AccountingTypeID == null) {
this.$ddlAccountingType.val('-1').trigger('change');
} else {
this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger('change');
}
if (isNaN(this.options.totalFixedPrice)) {
this.$fixedPrice.val('');
} else {
this.$fixedPrice.val(GetFormat(this.options.totalFixedPrice));
}
}
}
And this is the minified version:
_handleDDLValuesByContext: function() {
if (this.options.isCreate)
if (this.options.isChildCreation) this.$ddlBookingType.val(this.options.data.BookingTypeID), this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID), this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID), this.options.data.ServiceCategoryID == null ? (this.$ddlServiceCategory.val("-1").trigger("change"), this.options.data.PricePerUnit != null && this.$structureRate.val(GetFormat(this.options.data.PricePerUnit))) : this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger("change"), this.options.data.AccountingTypeID == null ? this.$ddlAccountingType.val("-1").trigger("change") : this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger("change");
else {
let t = this.options.structureSpecificData.BookingTypes,
i = null, // [SO-COMMENT] this shouldn't be named i
r = null;
for (let n = 0, u = t.length; n < u; n++) t[n].IsDefault && (i = t[n].ID, r = n);
let n = this.options.structureSpecificData.AllocationUnitTypes;
if (i == null) this.$ddlBookingType.val(t[0].ID), this.$ddlAllocationUnit.val(n[0].ID), this.$ddlEffortAllocationUnit.val(n[0].ID);
else {
let t = null;
this.$ddlBookingType.val(i).trigger("change");
n = [];
let f = this.options.structureSpecificData.BookingTypes,
u = this.options.structureSpecificData.AllocationUnitTypes;
for (let t = 0, i = u.length; t < i; t++) u[t].BaseUnitID == f[r].BaseUnitID && n.push(u[t]);
// [SO-COMMENT] here there is a second i that causes the problem
for (let i = 0, r = n.length; i < r; i++) n[i].IsDefault && (t = n[i].ID);
t == null ? (this.$ddlAllocationUnit.val(n[0].ID), this.$ddlEffortAllocationUnit.val(n[0].ID)) : (this.$ddlAllocationUnit.val(t), this.$ddlEffortAllocationUnit.val(t))
}
this.$ddlServiceCategory.val("-1")
} else this.$ddlBookingType.val(this.options.data.BookingTypeID), this.$ddlAllocationUnit.val(this.options.data.AllocationUnitID), this.$ddlEffortAllocationUnit.val(this.options.data.AllocationUnitID), this.options.data.IsParentElement ? (this.$ddlServiceCategory.val("-1").trigger("change"), isNaN(this.options.structureTotalCost) ? this.$structureTotalCost.val("") : this.$structureTotalCost.val(GetFormat(this.options.structureTotalCost)), isNaN(this.options.structureEffort) ? this.$structureEffortUnits.val("") : this.$structureEffortUnits.val(GetFormat(this.options.structureEffort))) : this.options.data.ServiceCategoryID == null ? (this.$ddlServiceCategory.val("-1").trigger("change"), this.options.data.PricePerUnit != null && (this.$structureRate.val(GetFormat(this.options.data.PricePerUnit)), this._checkTotalCostCalculation())) : this.options.data.PricePerUnit !== null ? (this.$structureRate.val(GetFormat(this.options.data.PricePerUnit)), this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID), this._checkTotalCostCalculation()) : this.$ddlServiceCategory.val(this.options.data.ServiceCategoryID).trigger("change"), this.options.data.AccountingTypeID == null ? this.$ddlAccountingType.val("-1").trigger("change") : this.$ddlAccountingType.val(this.options.data.AccountingTypeID).trigger("change"), isNaN(this.options.totalFixedPrice) ? this.$fixedPrice.val("") : this.$fixedPrice.val(GetFormat(this.options.totalFixedPrice))
}
My google searches for IIS minification scope problems didn't show any useful results. What could we try to investigate and fix this problem, other than not to use let?
I've been trying to create a trimLeft() function and I seem to be drawing blanks on the logic.
I'm not allowed to use built in functions like replace, splice, substr, substring, trim or toString.
I've been rolling with this:
function trimLeft(string){
var noSpace = '';
for(var o = 0; o < string.length; o++){
if (string.charAt(o) !== ' ' && string.charAt(o) !== "\t"){
noSpace += string.charAt(o);
}
}
return noSpace;
}
window.alert(trimLeft("|" + "\tAPPLE\t" + "|"));
However it removes all whitespace rather than just the left side. Any help would be appreciated.
Here's a working solution:
function trimLeft(string) {
for (var o = 0; o < string.length; o++){
if (string.charAt(o) !== ' ' && string.charAt(o) !== "\t"){
return string.substring(o);
}
}
}
window.alert("|" + trimLeft("\tAPPLE\t") + "|");
Note that as soon as a non-whitespace character is found, the rest of the string is returned immediately.
Also note that the test using window.alert() didn't work, because you tested the function with the string "|\tAPPLE\t|", which has no leading whitespace.
Here's a solution wihtout using any built-in string functions:
function trimLeft(string) {
var noSpace = "";
var isStart = true; // becomes false as soon as non-whitespace is found
for (var o = 0; o < string.length; o++) {
if (!isStart || (string[o] !== " " && string[o] !== "\t")) {
noSpace += string[o];
isStart = false;
}
}
return noSpace;
}
window.alert("|" + trimLeft("\tAPPLE\t") + "|");
window.alert("|" + trimLeft(" BANANA ") + "|");
sorry I'm french and I speak just few word in english.
I have a question maybe stupid :
Original code :var test = {
commandChar : "!",
};
for (i = 0; i < commands.length; i++) {
if (commands[i].hasOwnProperty('alt')) {
for (j = 0; j < commands[i].alt.length; j++) {
if ((index = text.toLowerCase().search(new RegExp("^\\" + test.commandChar + commands[i].alt[j].toLowerCase() + "\\b"))) >= 0) {
break;
}
}
}
if (index < 0) {
index = text.toLowerCase().search("^\\" + "[" + test.commandChar + ",##]" + commands[i].name.toLowerCase() + "\\b");
}
if (index > -1) {
var command = text.slice(index).split(" ");
if (!(commands[i].op || commands[i].elevated) || host || mod || authorised) {
if (!(commands[i].mod) || host || mod) {
commands[i].command(command, user);
}
}
else {
//sendChat("You have to be authorised to use " + commands[i].name + ".");
}
break;
}
}
This is an little bot, example.
If commandChar : "!". !help work but /help dont work.
I want just use this commandChar with many symbole
like
commandChar : "!", "/";
for use !help and /help
I think it should or array or regexpr
Sorry if I did not express myself properly it's complicated, thanks
There's many ways to do it but here's a quick one:
function isValidCommandChar(str) {
return "!/.".indexOf(str.charAt(0)) > -1;
}
isValidCommandChar("!help"); // true
isValidCommandChar("#help"); // false
isValidCommandChar("/help"); // true
isValidCommandChar(".help"); // true