Reputation: 1374
I'm trying to make a hashtag system using jQuery, but I have a problem with my code. So normally the code is working fine. But I want to remove duplicated tags in the written hashtags.
I've created this DEMO on codepen.io
In this demo when you write something and press space then the #
is automatically added in front of the word. I do not want users to be able to write the same word twice like: #abc #Abc #aBc #abC #ABC
I have created this code using regex but it didn't work.
// Remove duplicated hashatgs.
text = text.replace(/[#]{2,}/gi, function removeHashtags(x) { return '#'; });
Here is full code:
// Move cursor to the end.
function placeCaretAtEnd(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
// Add hashtags on each word.
function addHashtags(text) {
// Add hashtag.
text = text.replace(/([\w]+)/gi, function addHashtag(x){ return '#' + x; });
// Remove duplicated hashatgs.
text = text.replace(/[#]{2,}/gi, function removeHashtags(x) { return '#'; });
// Prevent double spaces
text = text.replace(/ /g, ' ');
text = text.trim();
// return results
return text;
}
// Convert characters to charCode
function toCharCode(char) { return char.charCodeAt(0); }
// Define special characters:
var characters = new Set([
0, 32, // space
13, // enter
// add other punctuation symbols or keys
]);
var forbiddenCharacters = new Set([
toCharCode("_"),
toCharCode("-"),
toCharCode("?"),
toCharCode("*"),
toCharCode("\\"),
toCharCode("/"),
toCharCode("("),
toCharCode(")"),
toCharCode("="),
toCharCode("&"),
toCharCode("%"),
toCharCode("+"),
toCharCode("^"),
toCharCode("#"),
toCharCode("'"),
toCharCode("<"),
toCharCode("|"),
toCharCode(">"),
toCharCode("."),
toCharCode(","),
toCharCode(";")
]);
$(document).ready(function() {
var element = '#text';
$(element).keypress(function (e) {
if (characters.has(e.keyCode)) {
// Get and modify text.
var text = $(element).text();
text = addHashtags(text);
// Save content.
$(element).text(text);
// Move cursor to the end
placeCaretAtEnd(document.querySelector(element));
} else if (forbiddenCharacters.has(e.keyCode)) {
e.preventDefault();
}
});
});
.container {
position:relative;
width:100%;
max-width:600px;
overflow:hidden;
padding:10px;
margin:0px auto;
margin-top:50px;
}
* {
box-sizing:border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
}
.addiez {
position:relative;
width:100%;
padding:30px;
border:1px solid #d8dbdf;
outline:none;
font-family: helvetica, arial, sans-serif;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}
.addiez::-webkit-input-placeholder {
/* Chrome/Opera/Safari */
color: rgb(0, 0, 1);
}
.addiez[contentEditable=true]:empty:not(:focus):before {
content:attr(placeholder);
color: #444;
}
.note {
position:relative;
width:100%;
padding:30px;
font-weight:300;
font-family: helvetica, arial, sans-serif;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
line-height:1.8rem;
font-size:13px;
}
.ad_text {
position:relative;
width:100%;
padding:10px 30px;
overflow:hidden;
font-weight:300;
font-family: helvetica, arial, sans-serif;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
line-height:1.8rem;
font-size:13px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="addiez" contenteditable="true" id="text" placeholder="Write something with space"></div>
<div class="ad_text" id="ad_text"></div>
Upvotes: 0
Views: 202
Reputation: 335
You could modify the AddHashtags function like this:
// Add hashtags on each word.
function addHashtags(text) {
// Add hashtag.
text = text.replace(/([\w]+)/gi, function addHashtag(x){ return '#' + x; });
// Remove duplicated words
text = text.replace(/\b(\w+)\b(?=.*\b\1\b)/gi, function removeDuplicates(x) { return ''; });
// Prevent single/double hashtags
text = text.replace(/[#]{2,}/gi, function removeDoubleHashtags(x) { return '#'; });
text = text.replace(/[#]{1}\s+/gi, function removeSingleHashtags(x) { return ''; });
// Prevent double spaces
text = text.replace(/ /g, ' ');
text = text.trim();
// return results
return text;
}
If there is a duplicate word it will overwrite the original entry, so if the list looks like: #hashtag #HaSHtag, then #HaSHtag will be the entry left. Including code to make sure everything is lowercase should be easy, if that´s what you are looking for.
The regex for removing duplicated words in the list comes from this SO answer: https://stackoverflow.com/a/16406260/6909765
Upvotes: 1
Reputation: 6081
One thing you could do is, split at #
and remove duplicates from array and then join the array with #
again.. by doing:
var unique = text.replace(/\s/g,'').split('#').filter(function(elem, index, self) {
return index == self.indexOf(elem.replace('\s+$',''));
})
text = unique.join(" #");
Upvotes: 1