jQuery string comparison behaves differently in IE7 - javascript

The following snippet is used in conjunction with a jQuery UI autocomplete element (#search). In Firefox, Chrome, etc. it behaves as expected and always returns true for the selected element. In Internet Explorer 7 it doesn't.
$('mySelector').filter(function() {
if ($(this).text().toLowerCase() == $('#search').val().toLowerCase()) {
return true;
}
});
For any hints about how this behaviour could be caused I will be very thankful!
EDIT: After pasting the nice analyze function by Šime Vidas I run the thing again and here comes the result of the comparison that should return true:
After some more investigation. I seems the comparison returns true (thank god, otherwise I would have needed a shrink). But the filter function return any valid objects. Which it should, if the comparison is true.
EDIT: Turns out I tested only cases where everything was fine. A few entries had double spaces between first and last name which didn't result in a FALSE evaluation in FF and Chrome but did in IE7.

Here:
function analyze( str ) {
var output, i;
output = 'String: ' + str + ' - Length: ' + str.length + '; ';
for ( i = 0; i < str.length; i += 1 ) {
output += str.charCodeAt( i ) + ' ';
}
return output;
}
And then:
alert( analyze( operand1 ) + '\n\n' + analyze( operand2 ) );
Live demo: http://jsfiddle.net/jsZzY/
The alert box will show you all code points of both strings....

Maybe $(this).text() in IE7 returns some additional chars. For example extra spaces, new lines (\r\n) etc. Try to output $(this).text() and $('#search').val() and visual compare this two strings.
Also you can try to add jQuery.trim functions, etc. If you rid out from all garbage your code should work.

Related

regex for nested parenthesis

Using javascript, im trying to make a node.js module to parse predicate logic statements.
I've been working on this regex for a bit and I just can't get it to behave the way i want
1. /\(((?:[^{}]*\([^{}]*\))*[^{}]*?)\)/
2. .replace(/\)((?:[^{}]*\)[^{}]*\))*[^{}]*?)\(/,'):::(')
the latter works fine on things like (a&s&d&a&s&d)->(a&s&(d)&s|(d)) but i just switched the delimiters...
what I'm trying to do is change a statement like
((r|a)&(s|r))&(~r)->(r|(q&r))->q
into
1->2->q
I can certainly write a procedural function to do it, that would be a fine solution. But Im really stuck on this.
The only real specification is the regex needs to respect the outermost parenthesis the most, and be able to replace separate ones.
Because this is not regex friendly I put togethor a couple of functions that do what you are looking for. The first matches parenthesis with depth:
function match_parens(code_to_test, level, opening, closing){
var sub_match, matched;
return code_to_test.replace(new RegExp('^([^'+opening+closing+']*(.))[\\s\\S]*$'), function(full_match, matched, $2, offset, original){
if ($2 == opening){
sub_match = match_parens(original.substr(offset+matched.length), level + 1, opening, closing);
matched = matched + sub_match
}
else if (level > 1){
sub_match = match_parens(original.substr(offset+matched.length), level - 1, opening, closing);
matched += sub_match;
}
return matched;
});
}
This function takes a string and returns everything up until the closing element.
The next function helps pulls a string passed to it apart, replacing all content in parenthesis with escalating numbers:
function pull_apart(testString){
var count = 1,
returnString = '',
tempIndex = testString.indexOf('(');
while (tempIndex !== -1){
returnString += testString.substring(0,tempIndex)+count;
count += 1;
testString = testString.substring(testString.indexOf('(') + match_parens(testString.substr(tempIndex + 1), 1, '(', ')').length+1)
tempIndex = testString.indexOf('(');
}
returnString += testString;
return returnString;
}
Running pull_apart('((r|a)&(s|r))&(~r)->(r|(q&r))->q') returns "1&2->3->q", which is what you are looking for. While this is not entirely regex, it is utilized in the paren matching function up above. I'm not sure if this fits whatever use case you had in mind, but hopefully it helps.

I'm having trouble with limitkeypress.js and IE10

In a project I'm working on, I have a textbox where the user has to input his name. To avoid the user from entering numbers I used the jquery.limitkeypress.js library written by Brian Jaeger and every thing was working perfectly until I tested the website in Internet Explorer 10. In IE10, you can input all the letters you want, and you can not input number or weird symbols just as I wanted but when I type a space and then a letter, I see the letter print right to the space and then the space disappearing and the latter shifting to the left. The weird thing is that if I wait like 30 seconds after typing the space to type the letter it works fine.
jquery.limitkeypress.js has some issue with ie, I recommend you to use a more powerful library.
http://github.com/RobinHerbots/jquery.inputmask
With this library you can use something like this:
$(".numbers").inputmask('Regex', {
mask: "9",
repeat: 11,
placeholder: ""
});
It works perfectly on ie. :)
Sorry i have not updated that plugin in a few years but...
jquery.limitkeypress now works with IE9+ there was an issue with how the selection was determined.
IE11 killed support for their document.selection but they kept the document.setSelectionRange which i was using to test what browser was being used...
IE9 enabled document.selectionStart and document.selectionEnd so i now check directly what browser version of IE peoples are using...
I added this to check for IE version:
var ie = (function(){
var undef,
v = 3,
div = document.createElement('div'),
all = div.getElementsByTagName('i');
while (
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
all[0]
);
return v > 4 ? v : undef;
}());
So my selection functions now look like this:
function getSelectionStart(o) {
if (ie < 9) {
var r = document.selection.createRange().duplicate()
r.moveEnd('character', o.value.length)
if (r.text == '') return o.value.length
return o.value.lastIndexOf(r.text)
} else return o.selectionStart
}
function getSelectionEnd(o) {
if (ie < 9) {
var r = document.selection.createRange().duplicate()
r.moveStart('character', -o.value.length)
return r.text.length
} else return o.selectionEnd
}

IE8 shows error: "Object doesn't support this property or method" on the line that uses filter() method

I am using this script to limit the characters on lines 1-3 on my textarea. It works in Firefox and Chrome. But in IE8, it shows an error: "Object doesn't support this property or method" on the line that uses filter() method.
Here's the code:
var result = jQuery('#result');
var my_textarea = jQuery('#mytext');
my_textarea.on('keyup', function(event){
var el = jQuery(this);
var lines = el.val().split('\n').length;
var chars = el.val().split('').filter(function(v){
return v != '\n';
}).length;
result.html('You have ' + lines + ' lines and ' + chars + ' chars');
if ((lines === 1 && chars > 20) || (lines === 2 && chars > 40) || (lines === 3 && chars > 60)) {
my_textarea.val( my_textarea.val() + "\n");
}
});
How do I resolve this?
IE8 doesn't support the Array.filter method.
MDN has a replacement.
filter (and several other methods on Array) are relatively new and aren't implemented in older browsers - not just IE8, but older Firefox too.
You may be interested in array_filter from PHPJS, as this produces the same effect.
Then again, looking at your code, wouldn't this be simpler?
var chars = el.val().replace(/\n/g,'').length;
Array.filter js polyfill:
[].filter||(Array.prototype.filter=function(g,f,j,i,h){
j=this;i=[];
for(h in j){~~h+""==h&&h>=0&&g.call(f,j[h],+h,j)&&i.push(j[h])}
return i
});
Jakob E

Convert HTML Character Entities back to regular text using javascript

the questions says it all :)
eg. we have >, we need > using only javascript
Update: It seems jquery is the easy way out. But, it would be nice to have a lightweight solution. More like a function which is capable to do this by itself.
You could do something like this:
String.prototype.decodeHTML = function() {
var map = {"gt":">" /* , … */};
return this.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);?/gi, function($0, $1) {
if ($1[0] === "#") {
return String.fromCharCode($1[1].toLowerCase() === "x" ? parseInt($1.substr(2), 16) : parseInt($1.substr(1), 10));
} else {
return map.hasOwnProperty($1) ? map[$1] : $0;
}
});
};
function decodeEntities(s){
var str, temp= document.createElement('p');
temp.innerHTML= s;
str= temp.textContent || temp.innerText;
temp=null;
return str;
}
alert(decodeEntities('<'))
/* returned value: (String)
<
*/
I know there are libraries out there, but here are a couple of solutions for browsers. These work well when placing html entity data strings into human editable areas where you want the characters to be shown, such as textarea's or input[type=text].
I add this answer as I have to support older versions of IE and I feel that it wraps up a few days worth of research and testing. I hope somebody finds this useful.
First this is for more modern browsers using jQuery, Please note that this should NOT be used if you have to support versions of IE before 10 (7, 8, or 9) as it will strip out the newlines leaving you with just one long line of text.
if (!String.prototype.HTMLDecode) {
String.prototype.HTMLDecode = function () {
var str = this.toString(),
$decoderEl = $('<textarea />');
str = $decoderEl.html(str)
.text()
.replace(/<br((\/)|( \/))?>/gi, "\r\n");
$decoderEl.remove();
return str;
};
}
This next one is based on kennebec's work above, with some differences which are mostly for the sake of older IE versions. This does not require jQuery, but does still require a browser.
if (!String.prototype.HTMLDecode) {
String.prototype.HTMLDecode = function () {
var str = this.toString(),
//Create an element for decoding
decoderEl = document.createElement('p');
//Bail if empty, otherwise IE7 will return undefined when
//OR-ing the 2 empty strings from innerText and textContent
if (str.length == 0) {
return str;
}
//convert newlines to <br's> to save them
str = str.replace(/((\r\n)|(\r)|(\n))/gi, " <br/>");
decoderEl.innerHTML = str;
/*
We use innerText first as IE strips newlines out with textContent.
There is said to be a performance hit for this, but sometimes
correctness of data (keeping newlines) must take precedence.
*/
str = decoderEl.innerText || decoderEl.textContent;
//clean up the decoding element
decoderEl = null;
//replace back in the newlines
return str.replace(/<br((\/)|( \/))?>/gi, "\r\n");
};
}
/*
Usage:
var str = ">";
return str.HTMLDecode();
returned value:
(String) >
*/
Here is a "class" for decoding whole HTML document.
HTMLDecoder = {
tempElement: document.createElement('span'),
decode: function(html) {
var _self = this;
html.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);/gi,
function(str) {
_self.tempElement.innerHTML= str;
str = _self.tempElement.textContent || _self.tempElement.innerText;
return str;
}
);
}
}
Note that I used Gumbo's regexp for catching entities but for fully valid HTML documents (or XHTML) you could simpy use /&[^;]+;/g.
There is nothing built in, but there are many libraries that have been written to do this.
Here is one.
And here one that is a jQuery plugin.

How can I get IE to recognize NBSP as NBSP instead of a space?

For the following JavaScript:
function EscapedString(str) {
var obj = document.createElement("span");
obj.innerHTML = str;
return "&#" + (obj.textContent || obj.innerText).charCodeAt(0) + ";";
}
alert(EscapedString(" "));
alert(EscapedString(" "));
alert(EscapedString("\xA0"));
IE returns for each value instead of   like every other browser correctly does. Is .innerText the wrong property for IE?
Here's it running on jsbin.
Ah, I can access the value of the text node created by the innerHTML and that returns the correct value:
function EscapedString(str) {
var obj = document.createElement("div");
obj.innerHTML = str;
return "&#" + (obj.firstChild.nodeValue || obj.textContent).charCodeAt(0) + ";";
}
Here's the latest script running on jsbin
...and here's the gist of the final code I ended up using
Try this out. Split up the '&' character from 'nbsp'
alert('&' + 'nbsp');
That worked for me. are you able to do that?
if not, perhaps you can convert to ascii???
edited
alert(String.fromCharCode(EscapedString(" ")))

Categories

Resources