I'm building a URL slug generator and I need to have the behavior be that if whats inputted is:
Ok Now Let's Do This & See
the output needs to be
ok-now-lets-do-this-see
Removing the &
, '
, and ,
characters
let newStr;
function slugifyString(str) {
let forbiddenChars = ["&", "'", ","];
newStr = str.toLowerCase().replace(/\s/g, '-');
if (newStr.includes(forbiddenChars) > -1) {
console.log('a forbidden character is present')
}
}
document.getElementById('slug-a-string-form').addEventListener('submit', function(e) {
e.preventDefault();
let inputStr = document.getElementById('string-to-slug').value
slugifyString(inputStr);
document.getElementById('slugged-string').innerHTML = newStr;
});
#slugged-string {
color: green;
font-size: 15px;
padding-top: 20px;
}
<form id="slug-a-string-form" action="POST">
<input type="text" id="string-to-slug" placeholder="enter the string to want to slug here...">
<input type="submit" value="Submit">
</form>
<div id="slugged-string"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
This works with a string like:
Testing This Out With Something TitleLike
And it slugifies, but it's saying that a forbidden character is present when it's not. Why is that happening?
How to check if a string contains text from an array of substrings in JavaScript?
I tweaked it a bit and tried this:
let newStr;
function slugifyString(str) {
let forbiddenChars = ["&", "'", ","];
newStr = str.toLowerCase().replace(/\s/g, '-');
let forbiddenCharsLength = forbiddenChars.length;
while(forbiddenCharsLength--) {
if (newStr.indexOf(forbiddenChars[forbiddenCharsLength])!=-1) {
if(forbiddenChars[forbiddenCharsLength] == "&") {
newStr = newStr.replace("-&", '')
} else {
newStr = newStr.replace(forbiddenChars[forbiddenCharsLength], '')
}
}
}
}
document.getElementById('slug-a-string-form').addEventListener('submit', function(e) {
e.preventDefault();
let inputStr = document.getElementById('string-to-slug').value
slugifyString(inputStr);
document.getElementById('slugged-string').innerHTML = newStr;
});
#slugged-string {
color: green;
font-size: 15px;
padding-top: 20px;
}
<form id="slug-a-string-form" action="POST">
<input type="text" id="string-to-slug" placeholder="enter the string to want to slug here...">
<input type="submit" value="Submit">
</form>
<div id="slugged-string"></div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Based on the output of the console:
it is: '
it is: &
It appears to be looping over each iteration of a forbidden character.
Inputting in:
Ok Now Let's Do This & See
We get the correct output now of:
ok-now-lets-do-this-see
But of we say:
Ok Now Let's Do This & That & See, what happens if we have more than one, comma
We get:
ok-now-lets-do-this-that-&-see-what-happens-if-we-have-more-than-one,-comma
I'm not sure why it's not removing every character that's forbidden, since we're looping over it.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
If pattern is a string, only the first occurrence will be replaced.
I do know that it replaces it only once, but
while(forbiddenCharsLength--) {
if (newStr.indexOf(forbiddenChars[forbiddenCharsLength])!=-1) {
if(forbiddenChars[forbiddenCharsLength] == "&") {
newStr = newStr.replace("-&", '')
} else {
newStr = newStr.replace(forbiddenChars[forbiddenCharsLength], '')
}
}
We're doing a while loop and executing an if command on each match so shouldn't the replace run for each instance..?
What am I missing here?
CodePudding user response:
Try use replaceAll function instead of replace.
CodePudding user response:
You might want to try this solution:
const s = "Ok Now Let's Do This & That & See, what happens if we have more than one, comma";
const slug = s.replaceAll(/[',&]/g, '').replaceAll(/\s /g, '-').toLowerCase();
console.log(slug);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can split the string into an array for each letter, then remove (map to "") each forbidden letter and proceed by replacing whitespaces with -
let forbiddenChars = ["&", "'", ","];
let newStr = str
.toLowerCase()
.split("")
.map(ch => forbiddenChars.includes(ch) ? '' : ch)
.join("")
.replace(/\s/g, '-');
function slugifyString(str) {
let forbiddenChars = ["&", "'", ","];
let newStr = str
.toLowerCase()
.split("")
.map(ch => forbiddenChars.includes(ch) ? '' : ch)
.join("")
.replace(/\s/g, '-');
if (newStr.includes(forbiddenChars) > -1) {
console.log('a forbidden character is present')
}
return newStr;
}
document.getElementById('slug-a-string-form').addEventListener('submit', function(e) {
e.preventDefault();
let inputStr = document.getElementById('string-to-slug').value
let outputStr = slugifyString(inputStr);
document.getElementById('slugged-string').innerHTML = outputStr;
});
#slugged-string {
color: green;
font-size: 15px;
padding-top: 20px;
}
<form id="slug-a-string-form" action="POST">
<input type="text" id="string-to-slug" placeholder="enter the string to want to slug here...">
<input type="submit" value="Submit">
</form>
<div id="slugged-string"></div>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You could iterate the array with unwanted characters/substrings and replace the final spaces with dashes.
function slugify(s) {
return ['&', ',', '\'']
.reduce((s, c) => s.replaceAll(c, ' '), s)
.replace(/\s /g, '-');
}
console.log(slugify('Ok Now Let\'s Do This & That & See, what happens if we have more than one, comma'));
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>