How to avoid a specific link in Tampermonkey - javascript

I've "created" a very small script for automatically clicking links on a specific site using TamperMonkey,
(function() {
'use strict';
var TargetLink = $("a:contains('Click Me')");
if (TargetLink.length)
window.location.href = TargetLink[0].href;
})();
When the link I'm trying to click, looks like this Click Me as an example.
What I'd like for the script to do, is avoid clicking on one specific "ID" and click all the other ones.
Example, I'd like to avoid clicking the ID 1, but click on 2, 3, and 4, where 4 are the amount of total ID's.
Not sure if I explained that as well as I would like to, but hopefully it's somewhat understandable.

You can use .filter() to remove the elements that you don't want.
In the filter I used split and slice to extract the id from href, then I check if the id is in idsBlacklist.
(function() {
'use strict';
var idsBlacklist = [
"1010101"
];
var query = "a:contains('Click Me')";
var TargetLink = $(query).filter(function () {
var id = this.href.split('/').slice(-1)[0];
return idsBlacklist.indexOf(id) < 0;
});
var blackListed = $(query).filter(function () {
var id = this.href.split('/').slice(-1)[0];
return idsBlacklist.indexOf(id) >= 0;
});
if (!blackListed.length && TargetLink.length) {
console.log(TargetLink[0].href);
//window.location.href = TargetLink[0].href;
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Click Me
Click Me
Click Me

Related

Javascript/Jquery toggle id with multiple variable

this is my first question, so apologies if not written clearly.
I want to dynamically toggle a comment form after reply button is pressed. There are multiple comments (in below example three) to which a form (with different id) can be rendered separately.
I am able to do this with static id for form but not with dynamically defined id...
I have tried this static approach and this works fine.
var functs_t = {};
functs_t['fun_27'] = $('#reply_comment_id_27').click(function() {$('#form_comment_id_27').toggle('slow');});
functs_t['fun_23'] = $('#reply_comment_id_23').click(function() {$('#form_comment_id_23').toggle('slow');});
functs_t['fun_21'] = $('#reply_comment_id_21').click(function() {$('#form_comment_id_21').toggle('slow');});
However, I am having struggling with a dynamic approach.
var i;
var functs = {};
for (i=0; i<comment_qs_id_list.length; i++) {
var comment_id = comment_qs_id_list[i].toString();
var reply_comment_id = 'reply_comment_id_'+ comment_id;
var form_comment_id = $('#'+reply_comment_id).attr('name');
// works >>> toggles comment 27
functs['func_reply_comment_'+comment_qs_id_list[i]] = $('#reply_comment_id_'+comment_qs_id_list[i]).click(function() {$('#'+'form_comment_id_27').toggle('slow');});
// does not work
//functs['func_reply_comment_'+comment_qs_id_list[i]] = $('#reply_comment_id_'+comment_qs_id_list[i]).click(function() {$('#'+form_comment_id).toggle('slow');});
// works >> toggles everything (but what I want is to hide initially and only toggle after clicking reply button)
//$('#'+form_comment_id).toggle('slow');
};
Thanks so much!

How do I sequentially go down a list of links each time a user clicks a button?

I start with a button that activates the function onclick:
<button onclick="openStuff();">Click here!</button>
Then, I have an array of links like so:
var links = [
"msn.com",
"google.com",
"youtube.com",
"bbc.com",
"facebook.com",
"cnn.com",
"fox.com",
"techcrunch.com"];
Finally, I define the function that randomly applies a link to the button from the above array:
openStuff = function () {
// get a random number between 0 and the number of links
var randIdx = Math.random() * links.length;
// round it, so it can be used as array index
randIdx = parseInt(randIdx, 10);
// construct the link to be opened
var link = 'https://' + links[randIdx];
// open it in a new window / tab (depends on browser setting)
window.open(link);
};
The problem is I need it to not be random. Rather, I need it to go down the list sequentially as the user clicks the button. If the user clicks the button once it should go to the first link. But, if this user clicks the button a second time it should go to the second link in the list.
For example: User clicks button: Go to first link, User clicks button again: go to second link, and so on.
var linkIndex = 0;
openStuff = function () {
//when no more links are available to click then return
if(links.length <= linkIndex) return;
// construct the link to be opened
var link = 'https://' + links[linkIndex];
// open it in a new window / tab (depends on browser setting)
window.open(link);
linkIndex++;
};
You need a global index that start in 0. Then, inside the function you increment it after open the link.
var link = 'https://' + links[index];
index++;
I would do it like this:
var special_button_state = 0;
const links = [
"msn.com",
"google.com",
"youtube.com",
"bbc.com",
"facebook.com",
"cnn.com",
"fox.com",
"techcrunch.com"
];
const openStuff = function () {
var link = 'https://' + links[special_button_state];
if(special_button_state < links.length-1) {
special_button_state++;
}
window.open(link);
console.log(link);
};
<button onclick="openStuff();">Click here!</button>
You could have another variable set to the first index of the array, something like:
var linkTarget = 0
and then update linkTarget in the function to increment appropriately:
openStuff = function () {
// construct the link to be opened
var link = 'https://' + links[linkTarget];
// open it in a new window / tab (depends on browser setting)
window.open(link);
// update the index
if (linkTarget++ == links.length)
linkTarget = 0
};
You could also implement a dynamic label so that you know where it's going:
<body onload="setLink()">
<button id="turntable-button" onclick="openStuff()" />
</body>
Label setter on page load (put the same getElementById() line in openStuff() after updating the index):
setLink = function() {
document.getElementById("turntable-button").innerHTML = links[linkTarget];
}

Replacing iframe source with Javascript - Can I use a loop?

I have a list of items (districts) on a page, and an iframe pulling in a map on the same page. When a user clicks on one of the districts, the JavaScript changes the source of the iframe to show a map of the district the user clicked.
My current code simply uses an "onclick" for each district, which then calls a function to change the source of the iframe.
I am wondering if I can simplify this code at all, possibly by using a loop? If I have 15 more districts to add to the page, will I have to add another "onclick" and another function for each one? Or is there an easier way that I am missing?
Simplified HTML:
<div id="districtlist">
Allen
Barren
Butler
<!--about 15 more links to follow-->
</div>
<iframe id="maparea" src="http://www.reddit.com"></iframe>
Javascript:
var a = document.getElementById("districtlist")
a.getElementsByTagName("a")[0].onclick = Allen;
a.getElementsByTagName("a")[1].onclick = Barren;
a.getElementsByTagName("a")[1].onclick = Butler;
//more lines...
function Allen() {
document.getElementById("maparea").src="http://www.youtube.com";
}
function Barren() {
document.getElementById("maparea").src="http://www.mentalfloss.com";
}
function Butler() {
document.getElementById("maparea").src="http://www.amazon.com";
}
//more functions...
I believe you could try this
var elems = document.getElementById("districtlist").querySelectorAll('a');
[].forEach.call(elems, function(elem) {
elem.onclick = function() {
var url = '';
switch(elem.innerText) {
case 'Allen':
url = "http://www.mentalfloss.com";
break;
case 'Barren':
url = "http://www.mentalfloss.com"
break;
case 'Butler':
url = "http://www.amazon.com";
break;
}
document.getElementById("maparea").src=url;
}
});

Creating whole new view based on current user's group sharepoint 2013

I am trying to generate a view based on the current user's group name. Group Name I am gathering from the custom list.
My question is how to apply the gathered group name to 'Group Name' column as a view parameter.
The only solution I figured:
I have created a view with a parameter.
I have added an HTML Form Web Part into the same page and connected it to the list view (sending the value to the parameter via web part connection). Then with a window.onload function I gather the current user's group name and pass this value via Form Postback function. But since the Postback function triggers full page reload, it falls into the endless loop of form submission > page reload.
Another way I have tried is attaching a click event listener to the BY MY GROUPS tab and it works perfectly, but the only disadvantage is that the page reloads each time user clicks on this tab, which I would like to avoid.
So the solution that I need is a way to post the form without a page reload.
Another option suggested here is to use CSR (client side rendering), but that has its own problems:
This code does not work as it is supposed to. In the console it shows me correct items, but the view appears untouchable.
Even if it worked, the other column values are still viewable in the column filter, as in this screenshot:
So, it seems that CSR just hides items from the view (and they are still available). In other words its behavior is different from, for example, a CAML query.
Or am I getting it wrong and there's something wrong with my code?
Below you can find my CSR code:
<script type='text/javascript'>
(function() {
function listPreRender(renderCtx) {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function() {
var currUserID = _spPageContextInfo.userId;
var cx = new SP.ClientContext('/sites/support');
var list = cx.get_web().get_lists().getByTitle('Group Members');
var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
cx.load(items, 'Include(_x006e_x50,DepID)');
cx.executeQueryAsync(
function() {
var i = items.get_count();
while (i--) {
var item = items.getItemAtIndex(i);
var userID = item.get_item('_x006e_x50').get_lookupId();
var group = item.get_item('DepID').get_lookupValue();
if (currUserID === userID) {
var rows = renderCtx.ListData.Row;
var customView = [];
var i = rows.length;
while (i--) {
var show = rows[i]['Group_x0020_Name'] === group;
if (show) {
customView.push(rows[i]);
}
}
renderCtx.ListData.Row = customView;
renderCtx.ListData.LastRow = customView.length;
console.log(JSON.stringify(renderCtx.ListData.Row));
break;
}
}
},
function() {
alert('Something went wrong. Please contact developer')
}
);
});
}
function registerListRenderer() {
var context = {};
context.Templates = {};
context.OnPreRender = listPreRender;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(context);
}
ExecuteOrDelayUntilScriptLoaded(registerListRenderer, 'clienttemplates.js');
})();
</script>

Extract field value present in javascript of a webpage

This is the script present in the html web-page.
jQuery(function($) {
new Shopify.OptionSelectors('productSelect', {
product: {
"id":626976579,
"title":"changedMacbook Air",
"handle":"macbook-air",
"description":"\u003cp\u003elightweight \u003c\/p\u003e\n\u003cp\u003eawesome performance\u003c\/p\u003e\n\u003cp\u003ewow display\u003c\/p\u003e\nHello World626976579[\"78000.00\"] [\"78000.00\"]\\n[\"78000.00\"] [\"78000.00\"]\u003cbr\u003e[\"78000.00\"]\u003cbr\u003e626976579\u003cbr\u003e626976579\u003cbr\u003e626976579",
"published_at":"2015-05-25T02:39:00-04:00",
"created_at":"2015-05-25T02:40:44-04:00",
"vendor":"Test_Store",
"type":"Computers",
"tags":[],
"price":7800000,
"price_min":7800000,
"price_max":7800000,
"available":true,
"price_varies":false,
"compare_at_price":null,
"compare_at_price_min":0,
"compare_at_price_max":0,
"compare_at_price_varies":false,
"variants":[{"id":1754837635,"title":"Default Title","options":["Default Title"],"option1":"Default Title","option2":null,"option3":null,"price":7800000,"weight":800,"compare_at_price":null,"inventory_quantity":-29,"inventory_management":null,"inventory_policy":"deny","available":true,"sku":"20","requires_shipping":true,"taxable":true,"barcode":"","featured_image":null}],"images":["\/\/cdn.shopify.com\/s\/files\/1\/0876\/1234\/products\/overview_wireless_hero_enhanced.png?v=1432536113"],"featured_image":"\/\/cdn.shopify.com\/s\/files\/1\/0876\/1234\/products\/overview_wireless_hero_enhanced.png?v=1432536113","options":["Title"],"content":"\u003cp\u003elightweight \u003c\/p\u003e\n\u003cp\u003eawesome performance\u003c\/p\u003e\n\u003cp\u003ewow display\u003c\/p\u003e\nHello World626976579[\"78000.00\"] [\"78000.00\"]\\n[\"78000.00\"] [\"78000.00\"]\u003cbr\u003e[\"78000.00\"]\u003cbr\u003e626976579\u003cbr\u003e626976579\u003cbr\u003e626976579"},
onVariantSelected: selectCallback,
enableHistoryState: true
});
How the value of "title" field be accessed, which here it is "changedMacbook Air" via my own JavaScript?
Thanks in advance.
I don't know if it will work but try
var myProduct = new Shopify.OptionSelectors('productSelect', {
....
})
then try
console.log(myProduct)
or you can try this:
$(document).ready(function(e){
console.log(document.title);
})
I think you might have to pass it through the callback.
$('#productSelect').on('change', function(e) {
var t = e.target || e.srcElement,
title = t.title.value;
selectCallback(title);
break;
}
}
});
//If you want to trigger it right away for some reason, just use this...
$("#productSelect").change();
Look for the code for option_selection.js in your products template or somewhere in your Snippets, Assets, or Templates. See this fiddle for an example of what the code looks like. option_selection.js
You might also want to check this link, it's setting up an onchange event on the product variants. I'm not sure what your ultimate goal is but I see you are working with product options and variants so it might be helpful.
You can modify option_selection.js if you need to, but more than likely you will just need some jquery in the document.ready.
Here is an example from option_selection.js that builds the names of each selector. Though you probably don't need to modify this, see link above.
Shopify.OptionSelectors.prototype.buildSelectors = function() {
for (var t = 0; t < this.product.optionNames().length; t++) {
var e = new Shopify.SingleOptionSelector(this, t, this.product.optionNames()[t], this.product.optionValues(t));
e.element.disabled = !1, this.selectors.push(e)
}
var o = this.selectorDivClass,
i = this.product.optionNames(),
r = Shopify.map(this.selectors, function(t) {
var e = document.createElement("div");
if (e.setAttribute("class", o), i.length > 1) {
var r = document.createElement("label");
r.htmlFor = t.element.id, r.innerHTML = t.name, e.appendChild(r)
}
return e.appendChild(t.element), e
});
return r
},

Categories

Resources