I'm trying replace some letters with numbers in JQuery, and I have initialized my object like this:
var myVar = {'a':1, 'b':2, 'c':3, 'd':4}
I'm getting the string from an input and I want to convert these letters immediately as the user is typing in text input. I want to do it via RegEx.
You can use input event, String.prototype.replace(), RegExp() with parameter new RegExp(keys.join("|"), "g" where keys are property names of myVar object
var myVar = {"a":1, "b":2, "c":3, "d":4};
var keys = Object.keys(myVar);
document.querySelector("input")
.addEventListener("input", function(e) {
e.target.value = e.target.value.replace(new RegExp(keys.join("|"), "g")
, function(match) {
return myVar[match]
});
});
<input type="text" />
Use :
Event : keyup event
Action :split & join for String AND map for Array.
$(INPUT_SELECTOR).keyup(function(event){
var newVal=$(this).val().split('').map(function(ch){
if(isFinite(ch) || !myVar[ch]){
return ch;
}else{
return myVar[ch];
}
}).join('');
$(this).val(newVal);
})
DEMO
Related
I want to retrieve inside an array all the elements who match multiple strings (all of them & not necessary words): like a search engine returning all results matching term_searched#1 && term_searched#2.
It's not a question about duplicates in the array (there's none), but about searching for a conjunction of elements: traditionally, the search is for one element, by himself or in disjunction with others (a|b|c). Just want to search (a && b && c).
I tried:
indexOf() : I can work only with one element to locate in the array.
match() : there is no AND operator in a regex expression (only | - sadly, it would be so simple). So I tried to inject these regex expressions
/(?=element1).*(?=element2)/gim
/(?=element1)(?=element2)/gim see here
The first regex expression works, but not at every time: seems very fragile...
So I don't know if I'm in the good direction (match) or if I can't figure what is the right regex expression... Need your advices.
// filter grid by searching on 'input' event
'input #search': (e)=> {
var keypressed = e.currentTarget.value;
// create array on 'space' input
var keyarr = keypressed.toLowerCase().split(" ");
// format each array's element into regex expression
var keyarrReg = [];
for(i = 0; i < keyarr.length; i++) {
var reg = '(?=' + keyarr[i] + ')';
keyarrReg.push(reg);
}
// array to regex string into '/(?=element1).*(?=element2)/gim' format
var searching = new RegExp(keyarrReg.join(".*"), 'mgi');
// set grid
var grid = new Muuri('#gridre', {
layout: {
fillGaps: true,
}
});
if (keypressed) {
// filter all grid's items (grid of items is an array)
grid.filter(function (item) {
var searchoperator = item.getElement().textContent.toLowerCase().match(searching);
// get items + only their text + lower case their text + return true (not false) in the value ('keypressed') is found in them
//var searchoperator = item.getElement().textContent.toLowerCase().indexOf(keypressed.toLowerCase()) != -1;
return searchoperator;
}
[....]
}
}
Edit with Gawil's answer adapted to my initial code (to help if needed)
// filter grid by searching on 'input' event
'input #search': (e)=> {
var keypressed = e.currentTarget.value;
// create array on 'space' input
var keyarr = keypressed.toLowerCase().split(" ");
// convert the array to a regex string, in a '^(?=.*word1)(?=.*word2).*$' format
// here is Gawil's answer, formatted by Teemu
var searching = new RegExp('^(?=.*' + keyarr.join(')(?=.*') + ').*$', 'm');
// set grid
var grid = new Muuri('#gridre', {
layout: {
fillGaps: true,
}
});
if (keypressed) {
// filter all grid's items (grid of items is an array)
grid.filter(function (item) {
// get items + only their text + lower case their text + delete space between paragraphs
var searchraw = item.getElement().textContent.toLowerCase().replace(/\r\n|\n|\r/gm,' ');
var searchoperator = searchraw.match(searching);
return searchoperator;
}
[....]
}
}
The code bellow will log each element of the array containing words cats and dogs.
It uses the regex ^(?=.*word1)(?=.*word2).*$To handle new lines, use this one instead :
^(?=(?:.|\n)*word1)(?=(?:.|\n)*word2).*$
You can add as many words as you want following the same logic, and it does not take order of the words in count.
It is very similar to what you tried, except that you have to do all (?=) checks before matching the string. Indeed, your first regex works only when the words are in the right order (element1 and then element2). Your second regex almost works, but you wrote only lookaheads, so it checks the presence of each word, but won't match anything.
var words = ["cats", "dog"]
var array = [
"this is a string",
"a string with the word cats",
"a string with the word dogs",
"a string with both words cats and dogs",
"cats rule everything",
"dogs rule cats",
"this line is for dog\nbut cats prefer this one"
]
var regexString = "^";
words.forEach(function(word) { regexString += ("(?=(?:.|\n)*"+word+")"); });
var regex = new RegExp(regexString);
array.forEach(function(str) { // Loop through the array
if(str.match(regex)) {
console.log(str); // Display if words have been found
}
});
If I've correctly understood your question, you've an array of strings, and some keywords, which have to be found from every index in the array to be accepted in the search results.
You can use a "whitelist", i.e. a regExp where the keywords are separated with |. Then iterate through the array, and on every member create an array of matches against the whitelist. Remove the duplicates from the matches array, and check, that all the keywords are in the list simply by comparing the length of the matches array to the count of the keywords. Like so:
function searchAll (arr, keywords) {
var txt = keywords.split(' '),
len = txt.length,
regex = new RegExp(txt.join('|'), 'gi'), // A pipe separated whitelist
hits; // The final results to return, an array containing the contents of the matched members
// Create an array of the rows matching all the keywords
hits = arr.filter(function (row) {
var res = row.match(regex), // An array of matched keywords
final, temp;
if (!res) {return false;}
// Remove the dups from the matches array
temp = {}; // Temporary store for the found keywords
final = res.filter(function (match) {
if (!temp[match]) {
// Add the found keyword to store, and accept the keyword to the final array
return temp[match] = true;
}
return false;
});
// Return matches count compared to keywords count to make sure all the keywords were found
return final.length === len;
});
return hits;
}
var txt = "Some text including a couple of numbers like 8 and 9. More text to retrieve, also containing some numbers 7, 8, 8, 8 and 9",
arr = txt.split('.'),
searchBut = document.getElementById('search');
searchBut.addEventListener('change', function (e) {
var hits = searchAll(arr, e.target.value);
console.log(hits);
});
<input id="search">
The advantage of the whitelist is, that you don't have to know the exact order of the keywords in the text, and the text can contain any characters.
I'm facing a problem.
I have this:
<input type="hidden" name="Boss" id="Boss" value="8,116,167,198,139,203,158,170,">
Actually I have this code in js:
// On click on element with class .Boss
$("form").on("click", ".Boss", function(event){
var clickedId = $(this).attr('value')+','; // give me 8,
var locationBtn = $('#Boss'); // Select the input
var locationBtnValue = $('#Boss').val(); // Take the select value
if(locationBtnValue.toString().indexOf(clickedId) == -1) { locationBtn.val(locationBtnValue + clickedId); }
else { locationBtn.val(locationBtnValue.replace(clickedId,'')); }
});
My problem is: if want to decide to remove the 8 my javascript do not remove the item 8, but the first occurrence it will find in my string, so 8,116,167,19**8,**139,203,158,170,. So it breaks my other item...
How can I make to do not break it ?
Thanks.
I do not know what your final outcome is, but I think you want it to be 116,167,198,139,203,158,170, In this case you can split and filter the array to get rid of the value.
var str = "8,116,167,198,139,203,158,170,"; //the input
var updated = str.split(",") //turn it into an array
.filter(function (val) { //loop through all the elements applying this function
return val!=="8"; //keep the item if the index does not match the item
}
).join(","); //turn array back into a string
One way to be consistent is by splitting it into an array and then removing the occurence.
// On click on element with class .Boss
$("form").on("click", ".Boss", function(event) {
var clickedId = $(this).attr('value'); // give me 8
var locationBtn = $('#Boss'); // Select the input
var locationBtnValue = locationBtn.val(); // Take the select value
var ids = locationBtnValue.split(','); //split into an array
var index = ids.indexOf(clickedId); //index of clickedId inside ids
if(index > -1) { //found
ids = ids.splice(index, 1); //remove from ids
} else {
ids.push(clickedId); //add to ids
}
locationBtn.val(ids.join(','));
});
That's what replace does when you pass it a string, it replaces the first occurrence.
You need to pass it a regular expression with the global modifier, like this
locationBtnValue.replace(/8,/g,'')
you can do the same thing with the RegExp constructor, and create a regular expression from the string you have
var clickedId = $(this).val() + ',';
var regex = new RegExp(clickedId, "g");
locationBtnValue.replace(regex,'');
I have the following array:
etst,tset,tets,ttest,teest,tesst,testt,4est,test,dest
I want to delete the value of an input box from the array, here's what I'm trying:
var el = document.getElementById('searchInput').value; // this is "test"
var toSearchFor = eld.slice(0,10); // the array above
for(var i=0; i < toSearchFor.length; i++) {
toSearchFor[i] = toSearchFor[i].replace(/el/g, "");
}
It's simply not replacing "test" with ""
How can I do that?
You can use Array.filter (see MDN) to filter out the desired value:
var arr = 'etst,tset,tets,ttest,teest,tesst,testt,4est,test,dest'.split(',')
,val = 'test'
document.querySelector('#result')
.innerHTML = arr.filter(function (v) {return v != val});
<div id="result"></div>
A text field example in this jsFiddle
for global replacement of a string stored in a variable u need to create an instance of RegExp explicitly, like this:
var regex = new RegExp(el, "g");
then use it in replace function:
toSearchFor[i] = toSearchFor[i].replace(regex, "");
The problem with your code is in your regular expression: /el/g. This is trying to match the letters el, instead of whatever it's in the el variable. You could have done it using the RegExp construtor.
// ...
regexp = new RegExp(el); // No need to use 'g' here since you're looking for the whole word
toSearchFor[i] = toSearchFor[i].replace(regexp, "");
// ...
Here's another way of doing it:
var eld = ['etst','tset','tets','ttest','teest','tesst','testt','4est','test','dest'];
// var el = document.getElementById('searchInput').value;
var el = 'test';
console.log(eld);
var index = eld.indexOf(el);
if (index >= 0) {
eld[index] = '';
}
console.log(eld);
Here's the output:
["etst", "tset", "tets", "ttest", "teest", "tesst", "testt", "4est", "test", "dest"]
["etst", "tset", "tets", "ttest", "teest", "tesst", "testt", "4est", "", "dest"]
In this case, we're using Array.prototype.indexOf, which returns the first index at which a given element can be found in the array, so that we can access that element directly (if found).
I hope that helps!
I want to edit the value of an input field! To detail i want to delete the text that that is defined an an array from the input:
So if i have for example:
<input value="hello what is your">
and this array:
var arr = ["hello","is"];
I want to change the value of the input to:
<input value="what your">
How should i start? Thanks http://jsfiddle.net/rRXAG/
How should i start?
1) Iteration - Since you already use jQuery, try with $.each.
2) string.indexOf() - returns -1 if it is not present
var arr = ["hello","is"];
$.each(arr, function (i, j) {
var inTxt = $('input').val();
if (inTxt.indexOf(j) != -1) {
$('input').val(inTxt.replace(j, ''));
}
});});
JSFiddle
var val=document.getElementById("yourid").value;
for(var i=0;i<arr.length;i++){
val.replace(arr[i],"")
}
document.getElementById("yourid").value=val;
This regexp do the job :
$('input').first().val().replace(new RegExp(arr.join('|'), 'g'), '');
Fiddle : http://jsfiddle.net/rRXAG/2/
Assuming the values are words separated by spaces, you can do this:
1) Store the values into a map
var map = {};
for (var i in arr) map[arr[i]] = true;
2) Get the value from your input (it's a string) and filter it
var inputVal = $('input').first().val();
var newValue = inputVal.split(" ").filter(function(x) {
return !map[x];
}).join(" ");
// Set new value
$('input').first().val(newValue);
The Problem
I'm trying to use the JavaScript string replace method to replace some text in a div if it contains a certain string. However, my code does not replace the string inside that div.
The Javascript
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
val.replace(NAME, '');
}
}
It doesn't work because .replace() is a String function and not a jQuery function; Strings in JavaScript are immutable, so .replac() returns the modified String which you then have to reassign to your element.
That said, you can use .text(fn) to perform the replacement in a single step:
$("div#like-list-").text(function(i, val) {
return val.replace(NAME, '');
});
Btw, I've removed the .indexOf() condition as well, because if NAME doesn't occur inside your string, the .replace() function will just return the original string.
You're editing the string, then simply throwing it away. Take the edited val and put it's contents back into the HTML element using a parameterized call to the text method.
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
$("div#like-list-").text(val.replace(NAME, ''));
}
}
replace() is javascript not jQuery and you need to reset the value to variable after replace as replace() returns the updated text;
ie;
val = val.replace(NAME, '');
so try:
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
val = val.replace(NAME, '');
}
}