I have dropdownlist with following html code that I grabbed from debug window. It is a code in blackbox that I can't get to. In this webpage I want to use javascript to remove the options if it does not start with 'SS '. How do I do that?
<select id="prgid" special="lists.specprog" name="UF-003054-1">
<option value=""> </option>
<option value="5488">SS Twain CE</option>
<option value="5487">Twain IS</option>
</Select>
I am doing something like this which is not working. Please help.
var select=document.getElementById('prgid');
for (i=0;i<select.length; i++) {
var prg = select.options[i].value;
if (!prg.substring,0,3) == 'SS ') {
select.remove(i);
}
}
You had the right idea. Try this:
var select = document.getElementById('prgid');
for (var i in select.children) {
if (select.children[i].innerHTML.match('SS') !== 0) {
select.children[i].outerHTML = '';
}
}
http://jsfiddle.net/howderek/35vagg9u/
var select=document.getElementById('prgid');
for (i=0;i<select.length; i++) {
var prg = select.options[i].text;
if (prg.substring(0,3) == 'SS ') {
select.remove(i);
}
}
Use the above javascript.
you have to use select.options[i].text to get option text. But if you use .value that will give you the option value. And see the syntax of .substring()
For code reference, see jsFiddle
Well, howderek already posted a good working alternative, but it may be worth posting a fixed version of your code for a better understanding of what went wrong. You were pretty close!
There were just a couple of missteps:
The condition within the if statement:
!prg.substring,0,3) == 'SS '
should instead have been:
prg.substring(0,3) != 'SS '
You were calling the substring() function incorrectly, and furthermore your placement of the ! operator would have caused you to compare a casted boolean against a string, rather than a string against a string (which is what you would want in this case).
Additionally, since you're actually accessing the text of the options, and not their values, you should use select.options[i].text; rather than select.options[i].value;.
Your resultant JavaScript would thus look like:
var select = document.getElementById('prgid');
for (i = 0; i < select.length; i++) {
var prg = select.options[i].text;
if (prg.substring(0, 3) != 'SS ') {
select.remove(i);
}
}
Here's a JSFiddle to demonstrate - note how all options that do not start with "SS " have been removed.
Hope this helps! Let me know if you have any questions.
You're close, you just missed a couple things
var prg = select.options[i].value;
//should be
var prg = select.options[i].text;
Should use .text, because .value will return 5488 and 5487, .text will return "SS Twain CE" And "Twain IS"
And your substring method wasn't formatted correctly, it should have been
if (prg.substring(0, 3) != 'SS ')
Putting it all together
var select=document.getElementById('prgid');
for (i=0;i<select.length; i++) {
var prg = select.options[i].text;
if (prg.substring(0, 3) != 'SS ') {
select.remove(i);
}
}
Related
I have been implementing a simple quiz for English. In that, we need to validate answers, which are entered by users in input field. In the current implementation, I am comparing the correct answer with user's answer exactly. Like,
HTML
<input type="text" id="answer" />
<button onclick="validate()">Validate</button>
Javascript
var question = "Do you like movies?",
answer = "No, I don't like movies.";
function validate() {
var userInput = document.getElementById('answer').value;
if(answer == userInput) {
console.log("correct");
} else {
console.log("wrong");
}
}
But I don't want validate exactly. Like, ignore case sensitive, commas, apostrophe, etc. For example if user enters,
i dont like movies
The answer can be correct. I don't know how start and where to start. Anyone please help.
One option would be to strip out all non-word characters and spaces, and compare the lower-case version of each replaced string:
var question = "Do you like movies?",
answer = "No, I don't like movies.";
const normalize = str => str
.replace(/[^\w ]/g, '')
.toLowerCase();
function validate(userInput) {
const noramlizedInput = normalize(userInput)
const noramlizedAnswer = normalize(answer);
if (noramlizedInput == noramlizedAnswer) {
console.log("correct");
} else {
console.log("wrong");
}
}
validate('No i dont like movies');
validate("NO!!!!! I DON''t like movies.");
Another option would be to loop through all possible substrings of the userInput and figure out which has the most overlap with the desired answer, but that's a whole lot more complicated.
An easier option would be to check to see how many overlapping words there are:
var question = "Do you like movies?",
answer = "No, I don't like movies.";
const normalize = str => str
.replace(/[^\w ]/g, '')
.toLowerCase()
.split(/\s+/)
function validate(userInput) {
const noramlizedInputArr = normalize(userInput);
const noramlizedAnswerArr = normalize(answer);
const overlapCount = noramlizedInputArr.reduce((a, word) => (
a + Number(noramlizedAnswerArr.includes(word))
), 0);
console.log(overlapCount);
if (overlapCount >= 4) {
console.log("correct");
} else {
console.log("wrong");
}
}
validate('No i dont like movies');
validate("NO!!!!! I DON''t like movies.");
validate("i dont like movies.");
validate("Yes I like movies.");
If you are interested in simply catching spelling errors and small variations, a standard metric is called edit distance or Levenshtein distance. This is a count of the minimum number of deletions, insertions, or substitutions you need to change one text into another. Strings like "No I don't like the movies" and "No I don't like the moveys" will have small edit distances.
Here's a quick and dirty recursive edit distance function that will give you an idea:
function validate(text, pattern) {
// some simple preprocessing
let p = pattern.toLowerCase().replace(/[^a-z]+/ig, '')
let t= text.toLowerCase().replace(/[^a-z]+/ig, '')
// memoize recursive algorithm
let matrix = Array.from({length: t.length + 1}, () => [])
function editDistance(text, pattern, i = 0, j = 0){
if(i == text.length && j == pattern.length) return 0
if(i == text.length) return pattern.length - j
if(j == pattern.length) return text.length - i
let choices = [
(matrix[i+1][j+1] || (matrix[i+1][j+1] = editDistance(text, pattern, i+1, j+1))) + (text[i].toLowerCase() === pattern[j].toLowerCase() ? 0 : 1),
(matrix[i+1][j] || (matrix[i+1][j] = editDistance(text, pattern, i+1, j))) + 1,
(matrix[i][j+1] || (matrix[i][j+1] = editDistance(text, pattern, i, j+1))) + 1
]
return Math.min(...choices)
}
return editDistance(t, p)
}
// similar strings have smaller edit distances
console.log(validate("No I dont lik moves","No i dont like movies"))
// a little less similar
console.log(validate("Yes I like movies","No i dont like movies"))
// totally different
console.log(validate("Where is the bathroom","No i dont like movies"))
// careful -- small edit distance !== close meaning
console.log(validate("I do like tacos","I don't like tacos"))
Picking a minimum acceptable distance works pretty well for matching strings with small typos. Of course, if you are trying to gauge user intent, none of these simple hues tics will work. Strings like "I love tacos" and "I loath tacos" have a small edit distance and you can't tell that they mean the opposite without knowledge of the language. If you need to do this level of checking you can try using a service like Watson Conversation that will return user intents to input.
I'm making a Ukrainian phonetic keyboard. People type in English, and the letters automatically change to the corresponding Ukrainian characters. However, when I'm using it, I sometimes need to write myself notes in English (they serve the same purpose as comments in code- for other people and for myself).
I'd like to indicate the start of a comment with a tag ("<"). How can I check if there's currently an open tag?
I'm thinking something like this:
if (number of "<" is greater than ">") {//if a tag has been opened and not closed
//disable translation, type in English
}
I understand how to disable the translation- however, I'm unsure about the
"if"
How can I check if
number of "<" is greater than ">"
Thanks!
You can count number of specific characters using .match()
In your case
var string = "<<<>>";
if ((string.match(/</g)||[]).length > (string.match(/>/g)||[]).length) {
console.log("More");
}
else {
console.log("Less or equal");
}
counting each of them is like below
var countGreaterThan = (temp1.match(/</g) || []).length;
var countLessThan = (temp1.match(/</g) || []).length;
and temp is the string value of the textarea
Depending on where your data is, you can do:
var data = document.querySelector('#data-container').innerHTML;
var isOpenTagPresent = getSymbolCount('<') > getSymbolCount('<');
if(isOpenTagPresent) {
//execute your logic
}
function getSymbolCount(symbol) {
var count = 0;
for(var i = 0; i < data.length; ++i) {
if(data[i] === symbol) {
count++;
}
}
return count;
}
Hope this helps, cheers!
Not certain if this can be done in regexp under javascript, but thought it would be interesting to see if it is possible.
So thought I would clean up a piece of html to remove most tags, literally just dropping them, so <H1><img><a href ....>. And that would be relatively simple (well, stole the basis from another post, thanks karim79 Remove HTML Tags in Javascript with Regex).
function(inString, maxlength, callback){
console.log("Sting is " + inString)
console.log("Its " + inString.length)
var regex = /(<([^>]+)>)/ig
var outString = inString.replace(regex, "");
console.log("No HTML sting " + outString);
if ( outString.length < maxlength){
callback(outString)
} else {
console.log("Lets cut first bit")
}
}
But then I started thinking, is there a way where I can control regex execution. So lets say that I want to keep certain tabs, like b,br,i and maybe change H1-6 to b. So in pseudo code, something like:
for ( var i in inString.regex.hits ) {
if ( hits[i] == H1 ) {
hits[i] = b;
}
}
The issue is that I want the text thats not HTML tags to stay as it is, and I want it to just cut out by default. One option would of course be to change the ones I want to keep. Say change <b> to [[b]], once that is done to all the ones of interest. Then put them back to <b> once all unknown have been removed. So like this (only for b, and not certain the code below would work):
function(inString, maxlength, callback){
console.log("Sting is " + inString)
console.log("Its " + inString.length)
var regex-remHTML = /(<([^>]+)>)/ig
var regex-hideB = /(<b>)/ig
var regex-showB = /([b])/ig
var outString = inString.replace(regex-hideB, "[b]");
outString = outString.replace(regex-remHTML, "");
outString = outString.replace(regex-showB, "<b>");
console.log("No HTML sting " + outString);
if ( outString.length < maxlength){
callback(outString)
} else {
console.log("Lets cut first bit")
}
}
But would it be possible to be smarter, writing cod ethat says here is a peice of HTML tag, run this code against the match.
As Tim Biegeleisen sai in its comment, maybe a better solution could be using a parser instead of a Regex...
By the way, if you want to control what is going to be changed by the regex you can pass a callback to the String.prototype.replace:
var input = "<div><h1>CIAO Bello</h1></div>";
var output = input.replace(/(<([^>]+)>)/gi, (val) => {
if(val.indexOf("div") > -1) {
return "";
}
return val;
})
;
console.log("output", output);
So i have this code:
function validateText(str)
{
var tarea = str;
var tarea_regex = /^(http|https)/;
if(tarea_regex.test(String(tarea).toLowerCase()) == true)
{
$('#textVal').val('');
}
}
This works perfectly for this:
https://hello.com
http://hello.com
but not for:
this is a website http://hello.com asdasd asdasdas
tried doing some reading but i dont where to place * ? since they will check the expression anywhere on the string according here -> http://www.regular-expressions.info/reference.html
thank you
From the looks of it, you're just checking if http or https exists in the string. Regular expressions are a bit overkill for that purpose. Try this simple code using indexOf:
function validateText(str)
{
var tarea = str;
if (tarea.indexOf("http://") == 0 || tarea.indexOf("https://") == 0) {
// do something here
}
}
Try this:
function validateText(string) {
if(/(http(s?)):\/\//i.test(string)) {
// do something here
}
}
The ^ in the beginning matches the start of the string. Just remove it.
var tarea_regex = /^(http|https)/;
should be
var tarea_regex = /(http|https)/;
((http(s?))\://))
Plenty of ideas here : http://regexlib.com/Search.aspx?k=URL&AspxAutoDetectCookieSupport=1
Have you tried using a word break instead of the start-of-line character?
var tarea_regex = /\b(http|https)/;
It seems to do what I think you want. See here: http://jsfiddle.net/BejGd/
I want to add the the following jQuery to the following pages only.
http://www.mywebsite.com/check-8.asp
http://www.mywebsite.com/edit-8.asp
http://www.mywebsite.com/cart-8.asp
So this means I want to add it where URL string contains either check-8, cart-8 or edit-8.
What is the best way with jQuery or JavaScript?
var text = $('#system td.td-main').html();
if (text != null)
{
var newtext = text.replace("Pris","<div id=\"pricebox\">Pris").replace("mva\)","mva\)</div>");
$('#system td.td-main').html(newtext);
}
Thanks in advance.
if(location.pathname.indexOf('check-8') > 0 || location.pathname.indexOf('cart-8') > 0 || location.pathname.indexOf('edit-8') > 0){
//your code here
}
Or you can use the following:
function testForCheckEditCart() {
var patt = /(check|edit|cart)-8/i;
return patt.test(location.href);
}
If you want a pure JavaScript solution, use the window.location property:
if (window.location.href.match(/(check|cart|edit)-8/).length > 0) {
// do your stuff
}
You can use the string.match method to check if it matches a Regex. You can also factor it out if you need to know which one it is:
var matches = window.location.href.match(/(check|cart|edit)-8/);
if (matches.length > 0) {
var action = matches[1]; // will be check, cart or edit
}