Need to click a bid button with Grease monkey script - xpath

I'm a bit stuck. I'm trying to create an Grease Monkey script that will automatically click an pop-up that appears on an auction site. I'v got the Xpat, but i'm too in expierienced with GM to get it to work.
Here is theelement inspection line i get from fire finder for firebug:
<input type="submit" style="width: 160px;" class="simplemodal-close" id="ctl00_mainContentPlaceholder_Button3" onclick="closePopup(); return false;" value="Back To Auctions" name="ctl00$mainContentPlaceholder$Button3">
and the firpath, xpath line is:
.//*[#id='ctl00_mainContentPlaceholder_Button3']
xpather line for full xpath:
/html/body/form[#id='aspnetForm']/div[#id='simplemodal-container']/div/div[#id='basic-modal-content']/div[#id='modal_winningBanner']/div/div[2]/div[2]/input[#id='ctl00_mainContentPlaceholder_Button3']
So what i used in my gm script to try to get it to click the button is as follows:
// #include *
// #version 0.1
// #description Automatically click // ==/UserScript==
click_popupBtn1 = function() {
var joinBtn=document.evaluate('//*[#id, "ctl00_mainContentPlaceholder_Button3"]'
,document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null).singleNodeValue.click();
alert(joinBtn);
if(!joinBtn) return false;
joinBtn.click();
return true;
}
click_popupBtn1 ();
I think ive got something wrong on the syntax, but dont know how to debug GM. I've only worked with turbo pascal a few years ago, but would like to get some simple things done in java and GM.
Any help would be apreciated.
Thanks
Ludwig

umm, I don't understand a lot of the words you used or this complex syntax.
but something like:
document.getElementById("ctl00_mainContentPlaceholder_Button3").click();
should work.

var joinBtn=document.evaluate('//*[#id, "ctl00_mainContentPlaceholder_Button3"]'
,document,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null).singleNodeValue.click();
The first argument above is not a syntactically legal XPath expression.
Should be:
//*[#id = "ctl00_mainContentPlaceholder_Button3"]

Related

Looking a way to automatically change one element on a website to another one. Hyperlink to a button exactly

So i have hyperlink at a webpage that is:
<b>456</b>
And i want it to be a button instead of hyperlink.
Like:
<input type="button" class="butt1" name="but" value="456" onclick="123.com'">
I tried to change it inside chrome dev tools and it works, well obviously since i jsut give it href adress manually. Sadly i have no expirience with tampermonkey or greasemonkey at all and very limited javascript knowledge. Wonder if it possible and would appretiate any help.
Here is a sample code based on your example...
First, you need to get the link
If it is only one link, find it based on a selector:
const a = document.querySelector('a.cs');
Create the input
const input = document.createElement('input');
input.type = 'button';
input.className = 'butt1';
input.name = 'but';
input.value = '456';
input.onclick = 'window.location.href=' + a.href;
Note: A better way is to use input.addEventListener('click', function) instead of onclick.
Replace the link with the button
a.parentNode.replaceChild(input, a);
If there are more than one links, then you need to get them and loop through them e.g.
const a = document.querySelectorAll('a.cs');

Getting DOM attributes of elements selected in CasperJS

I'm building a proof of concept test with CasperJS and I'm trying to wrap my head around when things are available and when they are not.
I'm a bit fuzzy on why evaluate() is required and why one cannot just get a page and go to town with document.querySelectorAll(), but that ends up giving me a nodeList with a length of zero... even after casper.echoing out the HTML and SEEING plenty of matching selectors.
Right now, I'm trying this:
var tile;
var pid;
casper.waitForSelector('.m-product-tile', function() {
tile = this.evaluate(function() {
return __utils__.findOne('.m-product-tile');
});
pid = this.evaluate(function()
return __utils__.findOne('.m-product-tile').getAttribute('data-pid');
});
//do cools stuff like click() on tile and make sure the URL has the pid in it
});
But this feels wrong as I am not sure __utils__.findOne() will always return the same element.
I'd love to be able to do this instead:
pid = tile.getAttribute('data-pid');
But when I attempt that, I get an error:
uncaughtError: TypeError: 'undefined' is not a function (evaluating 'tile.getAttribute('data-pid')')
Did tile somehow cease to be a DOMNode with a getAttributes method? Using typeof tile, it still thinks it's an object. I echoed out the DOMNode and it has a getAttributes key.
The code in the first example DOES work with getAttribute... so why does tile morph into something that no longer has a getAttributes method?
http://casperjs.readthedocs.org/en/latest/modules/casper.html#evaluate provides a pretty good answer... but still, I'd like to know why, if what the page is passing back, is a DOMNode, why can't I treat it like one?

Unable to remove element loaded by AJAX

I am trying to remove an element on AJAX success which was loaded and attached to the document during a previous AJAX call.
My code looks something like this:
$("#jobs-table-body").on("click", ".one-rc-button", function() {
var ctx = $.parseJSON($(this).siblings(".context").html());
$("#one-rc-candidate-id").val(ctx.candidateId);
$("#one-rc-job-id").val(ctx.jobId);
var loader = $("#wrapper").loader();
$.post($("#one-rc-form").attr("action"), $("#one-rc-form").serialize(), function(result) {
loader.remove();
if(result.success) {
// This works and returns 1
alert($("#candidate-row-" + result.rejectedCandidateId).length);
// This doesn't seem to be doing anything
$("#candidate-row-" + result.rejectedCandidateId).remove();
} else {
//$("#one-jc-messages").html(result.error);
}
});
});
The elements .one-rc-button and #candidate-row-<candidateId> were loaded by a previous AJAX call and they are attached to the document as I can very well see them on my page.
Now, on click of the previously generated .one-rc-button, I trigger a second AJAX call (which works fine) and on result.success, I want to delete the #candidate-row-<candidateId> (which is within the previously generated parent element).
The alert works and returns 1. So I know for sure that the selector is fine and it is matching one unique element.
What I don't understand is why it is unable to remove the element from the page.
Observations
I use Firefox 10.0.2 where this problem is reproducible.
On IE 8, it works (element gets removed)
On debugging the script on Firebug, I can verify that I have got a handle to the right eleemnt.
Try using FireBug to set a breakpoint on that line so you can see exactly what it's getting from that selector. Ideally break up the statement first, like this:
var unwantedDiv = $("#candidate-row-" + result.rejectedCandidateId);
unwantedDiv.remove(); // <-- Set a breakpoint on this line
You can then look at the unwantedDiv variable in the watch pane on the right of the firebug debugger and see what it is, what methods it has/has not got etc. I would assume that you are not getting back exactly what you think you are, possibly because of how you attached the div after the previous AJAX call. More information about JavaScript debugging with FireBug here.
Another option is to turn on strict warnings in the firebug console and see if you get any 'undefined method' errors, which don't stop the show on FireFox, but just bounce you out of that function. Do you get an error in IE?
Solved it by a really ugly workaround. I am still not sure what causes this behaviour.
if(result.success) {
var removeThis = $("#candidate-row-" + result.rejectedCandidateId);
removeThis.remove();
removeThis = $("#candidate-row-" + result.rejectedCandidateId);
if(removeThis.length != 0) {
removeThis.remove();
}
}
Now it works on both Firefox and IE.

jqGrid cell editing need to position the error message dialog

I'm using jqGrid with cell editing. I have setup the colModel properties using the editrules option. Everything works fine in that if I edit a cell and try to save an invalid value the grid displays an error dialog, but I need to know how to position the error message dialog that comes up because in the case of my layout it ends up behind a video. I'm not quite sure how to hook into this and there don't seem to be any obvious options on how to do it.
In this case the dialog I would be trying to manipulate is the one with ID of info_dialog.
Also I'm using the clientArray option for cellsubmit.
I realize this is rather old but upon searching I didn't find any indication this might have been added since, so I figured now that I've figured it out I'd let everyone know how I solved the positioning of mine.
$(document).ready(function ()
{
$.jgrid.jqModal = $.extend($.jgrid.jqModal || {}, {
beforeOpen: centerInfoDialog
});
});
function centerInfoDialog()
{
var $infoDlg = $("#info_dialog");
var $parentDiv = $infoDlg.parent();
var dlgWidth = $infoDlg.width();
var parentWidth = $parentDiv.width();
$infoDlg[0].style.left = Math.round((parentWidth - dlgWidth) / 2) + "px";
}
From what I could find in the jqGrid source code, you can add a beforeOpen and an afterOpen. In my case I'd rather position the thing before it's displayed (duh!). Would be nice if there was a parameter to hook it up in the grid declaration, but this does the trick in the mean time.
I hope this helps someone! I spent most of my afternoon on this!
Default value of zIndex parameter of info_dialog is 1000. The function info_dialog from grid.common.js part of jqGrid will be called from grid.celledit.js without usage a 4-th parameter which can change the option.
So the best pragmatical way which I could recomend you is to decrease zIndex value of your div with the video so that it will be less then 1000.

Jquery UI Slider - Input a Value and Slider Move to Location

I was wondering if anyone has found a solution or example to actually populating the input box of a slider and having it slide to the appropriate position onBlur() .. Currently, as we all know, it just updates this value with the position you are at. So in some regards, I am trying to reverse the functionality of this amazing slider.
One link I found: http://www.webdeveloper.com/forum/archive/index.php/t-177578.html is a bit outdated, but looks like they made an attempt. However, the links to the results do not exist. I am hoping that there may be a solution out there.
I know Filament has re-engineered the slider to handle select (drop down) values, and it works flawlessly.. So the goal would be to do the same, but with an input text box.
Will this do what you want?
$("#slider-text-box").blur(function() {
$("#slider").slider('option', 'value', parseInt($(this).val()));
});
Each option on the slider has a setter as well as a getter, so you can set the value with that, as in the example above. From the documentation:
//getter
var value = $('.selector').slider('option', 'value');
//setter
$('.selector').slider('option', 'value', 37);
UPDATE:
For dual sliders you'll need to use:
$("#amount").blur(function () {
$("#slider-range").slider("values", 0, parseInt($(this).val()));
});
$("#amount2").blur(function () {
$("#slider-range").slider("values", 1, parseInt($(this).val()));
});
You'll need to use Math.min/max to make sure that one value doesn't pass the other, as the setter doesn't seem to prevent this.
You were almost there when you were using the $("#slider-range").slider("values", 0) to get each value. A lot of jQuery has that kind of get/set convention in which the extra parameter is used to set the value.
I've done some work around the jQuery UI slider to make it accept values from a textbox, it may not be exactly what you were after but could help:
http://chowamigo.blogspot.com/2009/10/jquery-ui-slider-that-uses-text-box-for.html
$slider = $("#slider");
$("#amountMin").blur(function () {
$slider.slider("values", 0,Math.min($slider.slider("values", 1),parseInt($(this).val()) ) );
$(this).val(Math.min($slider.slider("values", 1),parseInt($(this).val())));
});
$("#amountMax").blur(function () {
$slider.slider("values",1,Math.max($slider.slider("values", 0),parseInt($(this).val()) ) );
$(this).val(Math.max($slider.slider("values", 0),parseInt($(this).val())));
});
I just used martin's code and updated the id to #slider also added the math.max as he suggested so the sliders won't overlap.

Resources