jQuery and JavaScript error in Sharepoint 2010 - javascript

i have downloaded a very nice script for realtime filter for sharepoint list:
https://instantlistfilter.codeplex.com/
i'm adding the code below. and i have two issues with it.
1. it is calling Google service, and i wonder if i can avoid that, since i'm not sure my company will be happy to know this list is going to Google each time someone is filtering it.
2. i'm getting error "Object doesn't support this property or method" for line 106 of the code, which causing the ribbon of the site including the "site action" dropdown button to disappear. I know it is related to the "show" command, but i have no clue how can i fix it.
As said above, i'm using sharepoint 2010. To install this code, i created a text document with it in my documents folder, then created below my list a CEW which is linked to that document. this method worked for me in another page with no issues.
Here is the full code as downloaded from the site above:
<script src="http://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1.2.6");
google.setOnLoadCallback(function() {
$(document).ready(function()
{
jQuery.extend(jQuery.expr[':'], {
containsIgnoreCase: function(a,i,m) {return (a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase().indexOf((m[3]||'').toLowerCase())>=0}
});
$("table.ms-listviewtable tr.ms-viewheadertr").each(function()
{
if($("td.ms-vh-group", this).size() > 0)
{
return;
}
var tdset = "";
var colIndex = 0;
$(this).children("th,td").each(function()
{
if($(this).hasClass("ms-vh-icon"))
{
// attachment
tdset += "<td></td>";
}
else
{
// filterable
tdset += "<td><input type='text' class='vossers-filterfield' filtercolindex='" + colIndex + "' /></td>";
}
colIndex++;
});
var tr = "<tr class='vossers-filterrow'>" + tdset + "</tr>";
$(tr).insertAfter(this);
});
$("input.vossers-filterfield")
.css("border", "1px solid #7f9db9")
.css("width", "100%")
.css("margin", "2px")
.css("padding", "2px")
.keyup(function()
{
var inputClosure = this;
if(window.VossersFilterTimeoutHandle)
{
clearTimeout(window.VossersFilterTimeoutHandle);
}
window.VossersFilterTimeoutHandle = setTimeout(function()
{
var filterValues = new Array();
$("input.vossers-filterfield", $(inputClosure).parents("tr:first")).each(function()
{
if($(this).val() != "")
{
filterValues[$(this).attr("filtercolindex")] = $(this).val();
}
});
$(inputClosure).parents("tr.vossers-filterrow").nextAll("tr").each(function()
{
var mismatch = false;
$(this).children("td").each(function(colIndex)
{
if(mismatch) return;
if(filterValues[colIndex])
{
var val = filterValues[colIndex];
// replace double quote character with 2 instances of itself
val = val.replace(/"/g, String.fromCharCode(34) + String.fromCharCode(34));
if($(this).is(":not(:containsIgnoreCase('" + val + "'))"))
{
mismatch = true;
}
}
});
if(mismatch)
{
$(this).hide();
}
else
{
$(this).show();
}
});
}, 250);
});
});
});
</script>

From what I can see, you're only using the Google code to download jQuery and setup callback when the script gets loaded. To avoid downloading from Google, can't you just load a local copy jQuery?
Download a minimized version of jQuery and upload it to your SharePoint site (Site Assets library or elsewhere).
Then in your code above replace this line
<script src="http://www.google.com/jsapi"></script>
with
<script src="/SiteAssets/{your jquery file name}"></script>
then you can just replace
google.setOnLoadCallback(function() {
$(document).ready(function() {
jQuery.extend(jQuery.expr[':'], {
containsIgnoreCase: function(a,i,m) {return (a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase().indexOf((m[3]||'').toLowerCase())>=0
}
});
});
with
$(function(){
jQuery.extend(jQuery.expr[':'], {
containsIgnoreCase: function(a,i,m) {return (a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase().indexOf((m[3]||'').toLowerCase())>=0
}
});

Related

Javascript doesn't work after website transfer

I have some issue with javascript after website transfer. All others scripts works fine but not this one
On demo version it works fine, but on live it do nothing and its giving 0 errors.
var vienasloop = true;
if (vienasloop) {
if (window.location.hash) {
$('li').on('click', function() { //here
first = $(this).siblings().eq(0).detach();
$(this).parent().prepend($(this).after(first).detach());
});
if (window.location.hash != "") {
$('li').eq(Number(window.location.hash.slice(1)) + 2).click();
}
}
}
$('body').html(String($('body').html()).replace("var vienasloop = true;",
"var vienasloop = false;"));
}
Jsfiddle
because in your code, the one property doesn't exist, try something like this :
if(window.location.hash) {
$('li').on('click' , function() { //here
first = $(this).siblings().eq(0).detach();
$(this).parent().prepend($(this).after(first).detach());
});
if (window.location.hash != "") {
$('li').eq(Number(window.location.hash.slice(1)) + 2 ).click();
}
}

jquery cannot get div to show using this selector

I am querying the Twitch API for a list of users in my database, to see if they are online.
I am essentially listing them all, with "display: none" and then unhiding if online:
$('.online_list').each(function (index) {
var tnick = $(this).data('tnick');
$.getJSON("https://api.twitch.tv/kraken/streams?client_id={:twitch_key}&channel="+tnick+"", function(a) {
if (a["streams"].length > 0)
{
alert(tnick);
$(this).show();
console.log(index + ": " + $( this ).text());
}
});
});
In my testing, the alert(tnick) works perfectly, so I know it's running. The problem is $(this).show(); just isn't working.
Here's example HTML:
<div class="online_list" data-tnick="test" style="display: none;">test:Twitch <span>(Online)</span></div>
<div class="online_list" data-tnick="test2" style="display: none;">test2:Twitch <span>(Online)</span></div>
this is the current scope object!
to fix your code you can do the following:
$('.online_list').each(function (index) {
var $that = $(this); // create a temp var that
var tnick = $that.data('tnick');
$.getJSON("https://api.twitch.tv/kraken/streams?client_id={:twitch_key}&channel="+tnick+"", function(a) {
if (a && a["streams"] && a["streams"].length > 0) {
alert(tnick);
$that.show(); // use that instead of this
console.log(index + ": " + $that.text());
}
});
});
Check out this resource for more information on scope & this: http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
EDIT:
Also, like #djxak suggests, you can use the element parameter of the callback, that is more simple and clean in my opinion.
The #djxak suggests:
$('.online_list').each(function (index, element) {
//... (scope1 code)
$.getJSON("", function(a) {
//... (scope2 code)
$(element).show();
});
});
My approach:
$('.online_list').each(function (index) {
//... (scope1 code)
var $current = $(this);
$.getJSON("", function(a) {
//... (scope2 code)
$current.show();
});
});
Info about each function and element parameter in jQuery docs: https://api.jquery.com/each/#each-function

javascript dependant drop down not working in IE 8

I have searched through here to find a javascript drop down that changes based on another drop down and the code I have works in Chrome. However, it doesn't work in IE 8.0.6 and I was wondering if anyone could highlight the part that isn't working, or suggest another workaround (JQuery, CSS etc).
When I load this in IE, the second drop down is completely blank. The first drop down has a variation of the arrays, when a user selects one of those, they are then presented with the options in the array. So if I select iAffordability, i will be presented with the three values in the array.
Here is the code I am using
iAffordability = new Array("Unable to Get Mortgage", "Cant Afford to Move", "Price");
iDisintruction = new Array("Branch Disinstructed");
iCourtOrder = new Array("Court Order");
iLackofComms = new Array("Marketing", "Viewings", "Offers");
iLackofOffers = new Array("Not Happy with Amount", "Not Happy with Quality");
populateSelect();
$(function () {
$('#WD').click(function () {
populateSelect();
});
});
function populateSelect() {
WD = $('#WD').val();
$('#Sub').html();
if (WD == 'iAffordability') {
$('#Sub').empty();
iAffordability.forEach(function (t) {
$('#Sub').append('<option>' + t + '</option>');
});
}
if (WD == 'iDisintruction') {
$('#Sub').empty();
iDisintruction.forEach(function (t) {
$('#Sub').append('<option>' + t + '</option>');
});
}
if (WD == 'iLackofComms') {
$('#Sub').empty();
iLackofComms.forEach(function (t) {
$('#Sub').append('<option>' + t + '</option>');
});
}
if (WD == 'iLackofOffers') {
$('#Sub').empty();
iLackofOffers.forEach(function (t) {
$('#Sub').append('<option>' + t + '</option>');
});
}
}
JS Fiddle
UPDATE:
The code worked, I just had to add in:
if (!window.console) console = {log: function() {}};
to my existing JS.
I'm going to suggest a refactoring and DRYing of your code:
var lists = {
iAffordability: ["Unable to Get Mortgage", "Cant Afford to Move", "Price"],
iDisintruction: ["Branch Disinstructed"],
iCourtOrder: ["Court Order"],
iLackofComms: ["Marketing", "Viewings", "Offers"],
iLackofOffers: ["Not Happy with Amount", "Not Happy with Quality"]
};
$(function () {
populateSelect();
$('#WD').change(function () {
populateSelect();
});
});
function populateSelect() {
var WD = $('#WD').val(), $sub = $('#Sub');
$sub.empty();
$.each(lists[WD] || ["Error"], function(_, t) {
$sub.append('<option>' + t + '</option>');
});
}
This should work even in older versions of IE because it uses the jQuery $.each function instead of Array.prototype.forEach - as RobG pointed out, this function was only added in IE9 (ah, if only IE forced itself to update like Chrome does...) and it should be much easier to expand in future.

how to make the jquery function load before one ajax function finish

How do I fire one event before the previous function completed its function?
I have the following AJAX code :
var BrainyFilter = {
//...
init: function (opts) {},
changeTotalNumbers: function (data) {
jQuery(BrainyFilter.filterFormId).find('.bf-count').remove();
jQuery(BrainyFilter.filterFormId).find('option span').remove();
jQuery(BrainyFilter.filterFormId).find('select').removeAttr('disabled');
jQuery('.bf-attr-filter').not('#bf-price-container').find('input, option')
.attr('disabled', 'disabled')
.parents('.bf-attr-filter')
.addClass('bf-disabled');
if (data && data.length) {
for (var i = 0; i < data.length; i++) {
jQuery('.bf-attr-' + data[i].id + ' .bf-attr-val').each(function (ii, v) {
if (jQuery(v).text() == data[i].val) {
var parent = jQuery(v).parents('.bf-attr-filter').eq(0);
var isOption = jQuery(v).prop('tagName') == 'OPTION';
var selected = false;
if (isOption) {
jQuery(v).removeAttr('disabled');
selected = jQuery(v)[0].selected;
} else {
parent.find('input').removeAttr('disabled');
selected = parent.find('input')[0].checked;
}
parent.removeClass('bf-disabled');
if (!selected) {
if (!isOption) {
parent.find('.bf-cell').last().append('<span class="bf-count">' + data[i].c + '</span>');
} else {
jQuery(v).append('<span> (' + data[i].c + ')</span>');
}
}
}
});
}
jQuery('.bf-attr-filter input[type=checkbox]').filter(':checked')
.parents('.bf-attr-block').find('.bf-count').each(function (i, v) {
var t = '+' + jQuery(v).text();
jQuery(v).text(t);
});
// since opencart standard filters use logical OR, all the filter groups
// should have '+' if any filter was selected
if (jQuery('.bf-opencart-filters input[type=checkbox]:checked').size()) {
jQuery('.bf-opencart-filters .bf-count').each(function (i, v) {
var t = '+' + jQuery(v).text().replace('+', '');
jQuery(v).text(t);
});
}
}
// disable select box if it hasn't any active option
jQuery(BrainyFilter.filterFormId).find('select').each(function (i, v) {
if (jQuery(v).find('option').not('.bf-default,[disabled]').size() == 0) {
jQuery(v).attr('disabled', 'true');
}
});
},
//...
} // close the BrainyFilter
I also have another jQuery file running to get the bf-count value using $('.bf-count').text().
When the page load, the bf-count value is empty. Since the code above inject the bf-count, I will need to wait until it finishes the for loop in order to get the bf-count value.
What is the best way to approach this?
without knowing how the second js file is loaded, I can only give you a guesstimate suggestion.
If you want to run the second js file code after the page is fully loaded, you can wrap the code in:
jQuery(window).load(function(){
//your code here. runs after the page is fully loaded
});
jQuery documentation: http://api.jquery.com/load-event/
"The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object."

Reload all images on page

I'm trying to get all the images in the page to reload including backgound-image: rules
I have some semi working code but I want to know if there is an easier way of doing this.
function cacheBuster(url) {
return url.replace(/\?cacheBuster=\d*/, "") + "?cacheBuster=" + new Date().getTime().toString();
}
$("img").each(function() {
this.src = cacheBuster(this.src);
});
$("*").each(function() {
var bg_img = $(this).css("background-image");
if (bg_img !== "none") {
var url = /url\((.*)\)/i.exec(bg_img);
if (url) {
$(this).css("background-image", "url(" + cacheBuster(url[1]) + ")");
}
}
});
Looks fine but you are missing inputs with type=image, that is images that act as a submit button. You can include them by adding following code
$("img, input[type=image]").each(function() {
this.src = cacheBuster(this.src);
});
Also you can change the code where you loop through all elements, just to include visible ones, if it is acceptable in your case.
$("*:visible")
Hope this helps.

Categories

Resources