I'm trying to write a bookmarklet that will capture some parameters from a URL and send that to a script (the url in the post is just a dummy atm).
The problem is, I try to include jQuery to the page so I can use a $.post later. When trying to run the bookmarklet I get the following error in the console:
Uncaught ReferenceError: $ is not defined
I can see the jQuery is succesfully appended by looking at the Elements tab in the browser. Any tips on how to solve this?
You can see the bookmarklet below:
javascript:
function appendScript() {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";
head.appendChild(script);
}
appendScript();
function parseUri (str) {
var o = parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) uri[o.q.name][$1] = $2;
});
return uri;
};
parseUri.options = {
strictMode: false,
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:#]*)(?::([^:#]*))?)?#)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:#]+:[^:#\/]*#)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:#]*)(?::([^:#]*))?)?#)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};
couponCode = parseUri(window.location.search).queryKey['couponCode'];
customerId = parseUri(window.location.search).queryKey['customerId'];
function showModal() {
if (couponCode != null) {
alert("Here is your coupon. Make sure to use it at checkout!" + couponCode);
}
}
showModal();
function parakeetCommunicator() {
if (couponCode != null) {
console.log("Sending data to Parakeet...");
$.post( "http://test.com/datascript.go", { customerId: customerId, couponCode: couponCode })
.done(function( data ) {
console.log("Succesfully posted the coupon was viewed to Parakeet server.");
});
}
}
parakeetCommunicator();
Script is loaded asychronously, you could fix it using onload event of script e.g:
var script = document.createElement("script");
script.onload = parakeetCommunicator;
script.src = ...;
And remove other call to this method.
If you only need jQuery for relative ajax wrapper, you should be interrested in building your own jquery version to support only these methods, see: http://projects.jga.me/jquery-builder/
Related
I'm using a script to extract data from google search console in a sheet.
I built a sidebar to chose on which website the user want to analyse his data.
For that i have a function that can list all sites link to the google account, but i have an error when i try to execute this function in my html file.
I use withSuccessHandler(function) method which sets a callback function to run if the server-side function returns successfully. (i have a OAuth2.0.gs file where is my getService function.
The error is "service.hasAccess is not a function at listAccountSites" where listAccountSites is my function. Here's an extract of my html file:
<script src="OAuth2.0.gs"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
$(function() {
var liste = google.script.run.withSuccessHandler(listAccountSites)
.getService();
console.log(liste);
});
function listAccountSites(service){
if (service.hasAccess()) {
var apiURL = "https://www.googleapis.com/webmasters/v3/sites";
var headers = {
"Authorization": "Bearer " + getService().getAccessToken()
};
var options = {
"headers": headers,
"method" : "GET",
"muteHttpExceptions": true
};
var response = UrlFetchApp.fetch(apiURL, options);
var json = JSON.parse(response.getContentText());
Logger.log(json)
console.log('if')
var URLs = []
for (var i in json.siteEntry) {
URLs.push([json.siteEntry[i].siteUrl, json.siteEntry[i].permissionLevel]);
}
/*
newdoc.getRange(1,1).setValue('Sites');
newdoc.getRange(1,3).setValue('URL du site à analyser');
newdoc.getRange(2,1,URLs.length,1).setValues(URLs);
*/
console.log(URLs);
} else {
console.log('else')
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s', authorizationUrl);
Browser.msgBox('Open the following URL and re-run the script: ' + authorizationUrl);
}
return URLs;
}
</script>
i found the solution.
Jquery is useless here, you just have to use google.script.run.yourfunction() to run your gs. function on your html sidebar.
I am fetching html from a website. I want to get specific html from that page not all how to get that? I have tried following;
before appending data to target below
container.html(data);
I want to do like data.find('.site-header').html(); and then do container.html(data);
How can I achieve that?
DEMO
HTML
<div id="target"></div>
Script
$(function () {
var container = $('#target');
var url = 'http://aamirshahzad.net';
$.getJSON("http://query.yahooapis.com/v1/public/yql?" +
"q=select%20*%20from%20html%20where%20url%3D%22" + encodeURIComponent(url) +
"%22&format=xml'&callback=?",
function (data) {
if (data.results[0]) {
var data = filterData(data.results[0]);
container.html(data);
} else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg).focus().effect('highlight', {
color: '#c00'
}, 1000);
}
});
});
function filterData(data) {
// filter all the nasties out
// no body tags
data = data.replace(/<?\/body[^>]*>/g, '');
// no linebreaks
data = data.replace(/[\r|\n]+/g, '');
// no comments
data = data.replace(/<--[\S\s]*?-->/g, '');
// no noscript blocks
data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g, '');
// no script blocks
data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g, '');
// no self closing scripts
data = data.replace(/<script.*\/>/, '');
// [... add as needed ...]
return data;
}
Quite simply;
container.html($(data).find('.site-header'));
Add this line after container.html(data);:
container.html(container.find(".site-header"));
Here is your updated JSFiddle
I have this ajax call here in a script tag at the bottom of my page. Everything works fine! I can set a breakpoint inside the 'updatestatus' action method in my controller. My server gets posted too and the method gets called great! But when I put the javascript inside a js file the ajax call doesn't hit my server. All other code inside runs though, just not the ajax post call to the studentcontroller updatestatus method.
<script>
$(document).ready(function () {
console.log("ready!");
alert("entered student profile page");
});
var statusdropdown = document.getElementById("enumstatus");
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById("enumstatus");
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
</script>
Now I put this at the bottom of my page now.
#section Scripts {
#Scripts.Render("~/bundles/studentprofile")
}
and inside my bundle.config file it looks like this
bundles.Add(new ScriptBundle("~/bundles/studentprofile").Include(
"~/Scripts/submitstatus.js"));
and submitstatus.js looks like this. I know it enters and runs this code because it I see the alert message and the background color changes. So the code is running. Its just not posting back to my server.
$(document).ready(function () {
console.log("ready!");
alert("submit status entered");
var statusdropdown = document.getElementById('enumstatus');
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById('enumstatus');
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
});
In the console window I'm getting this error message.
POST https://localhost:44301/Student/#Url.Action(%22UpdateStatus%22,%20%22Student%22) 404 (Not Found)
Razor code is not parsed in external files so using var id = "#Model.StudentId"; in the main view will result in (say) var id = 236;, in the external script file it will result in var id = '#Model.StudentId'; (the value is not parsed)
You can either declare the variables in the main view
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
and the external file will be able to access the values (remove the above 2 lines fro the external script file), or add them as data- attributes of the element, for example (I'm assuming enumstatus is a dropdownlist?)
#Html.DropDownListFor(m => m.enumStatus, yourSelectList, "Please select", new { data_id = Model.StudentId, data_url = Url.Action("UpdateStatus", "Student") })
which will render something like
<select id="enumStatus" name="enumStatus" data-id="236" data-url="/Student/UpdateStatus">
Then in the external file script you can access the values
var statusbubble = $('#statusbubble'); // cache this element
$('#enumStatus').change(function() {
var id = $(this).data('id');
var url = $(this).data('url');
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
....
});
// suggest you add/remove class names instead, but if you want inline styles then
if (status == someValue) { // the value of the first option?
statusbubble.css('backgroundColor', '#3fb34f');
} else {
statusbubble.css('backgroundColor', '#b23f42');
};
});
Started messing around with Vimeo API in an attempt to create a clickable gallery like this (http://www.aideffectiveness.org/busanhlf4/vimeo/php-example.php). However, when I moved some of the code into a "script.js" file as a way to organize my code from the other parts of the site, the json callback keeps saying that the 'embedVideo' function is not defined. Any ideas?
The "script.js" file is placed at the bottom of the page and has the following:
var NS = NS || NS;
NS = {
videoInit: function() {
var oEmbedUrl = 'http://vimeo.com/api/oembed.json';
var oEmbedCallback = 'embedVideo';
var videoid = "";
if(videoid == '' ){
videoid = '23515961';
}
function embedVideo( video ) {
var videoEmbedCode = video.html;
document.getElementById('embed').innerHTML = unescape(videoEmbedCode);
}
function init() {
loadScript(oEmbedUrl + '?url=http://vimeo.com/' + videoid + '&height=380&width=700&callback=' + oEmbedCallback);
}
function loadScript( url ) {
var js = document.createElement('script');
js.setAttribute('src', url);
document.getElementsByTagName('head').item(0).appendChild(js);
}
init();
}
}
$(function() {
NS.videoInit();
});
The HTML:
<div id="wrapper">
<div id="embed"></div>
</div>
embedVideo is a local (private) function inside of the init method. Nothing outside it can see it. That's why your AJAX callback is throwing that error.
You can fix this by making embedVideo a proper method of NS, so that's it's visible to your ajax callback
NS = {
embedVideo: function( video ) {
var videoEmbedCode = video.html;
document.getElementById('embed').innerHTML = unescape(videoEmbedCode);
},
videoInit: function() {
var oEmbedUrl = 'http://vimeo.com/api/oembed.json';
var oEmbedCallback = 'embedVideo';
var videoid = "";
if(videoid == '' ){
videoid = '23515961';
}
I have a YUI dialog that submits a form to a Java servlet. The servlet returns html and javascript. I take the response and put it into a div on the page and then eval the javascript that is within the div.
My problem is that I get an error in the firebug console saying "YAHOO is not defined" as soon as the servlet returns.
I do not include the YUI js files in the servlet as I didn't think I would need them, I would expect the files included in the head of the main page would be sufficient.
If I remove all references to YUI from the javascript returned by my servlet then everything works well.
What should I do to stop getting this error as soon as my servlet returns?
My Servlet returns something along the lines of:
<div id="features">some html to display</div>
<script id="ipadJS" type='text/javascript'>
var editButton1 = new YAHOO.widget.Button('editButton1', { onclick: { fn: editButtonClick, obj: {id: '469155', name : 'name 1'} } });
var editButton2 = new YAHOO.widget.Button('editButton2', { onclick: { fn: editButtonClick, obj: {id: '84889', name : 'name 2'} } });
</script>
Here is the code that I used to create the dialog, i use the handleSuccess function to put my response from my servlet into the page (note that even though im not actively putting the javascript into the page it still throws the 'YAHOO not defined' error.):
YAHOO.namespace("ipad");
YAHOO.util.Event.onDOMReady(function () {
// Remove progressively enhanced content class, just before creating the module
YAHOO.util.Dom.removeClass("createNewFeature", "yui-pe-content");
// Define various event handlers for Dialog
var handleSubmit = function() {
this.submit();
};
var handleCancel = function() {
this.cancel();
};
var handleSuccess = function(o) {
var response = o.responseText;
var div = YAHOO.util.Dom.get('features');
div.innerHTML = response;
};
var handleFailure = function(o) {
alert("Submission failed: " + o.status);
};
// Instantiate the Dialog
YAHOO.ipad.createNewFeature = new YAHOO.widget.Dialog("createNewFeature",
{ width : "450px",
fixedcenter : true,
visible : false,
constraintoviewport : true,
buttons : [ { text:"Submit", handler:handleSubmit, isDefault:true },
{ text:"Cancel", handler:handleCancel } ]
});
// Validate the entries in the form to require that both first and last name are entered
YAHOO.ipad.createNewFeature.validate = function() {
var data = this.getData();
return true;
};
YAHOO.ipad.createNewFeature.callback = { success: handleSuccess,
failure: handleFailure,
upload: handleSuccess };
// Render the Dialog
YAHOO.ipad.createNewFeature.render();
var createNewFeatureShowButton = new YAHOO.widget.Button('createNewFeatureShow');
YAHOO.util.Event.addListener("createNewFeatureShow", "click", YAHOO.ipad.clearFeatureValues, YAHOO.ipad.clearFeatureValues, true);
var manager = new YAHOO.widget.OverlayManager();
manager.register(YAHOO.ipad.createNewFeature);
});
I don't know your use case exactly, but if you just need to create some buttons on the fly based on server response, than it would IMO be better to return JSON or XML data with the variable data and then create the buttons. Something like
var reply = eval('(' + o.responseText + ')');
var editButton1 = new YAHOO.widget.Button('editButton1',
{ onclick: { fn: editButtonClick,
obj: {id: reply[id], name : reply[name]}
} })
And if you really want to append a script node, then the following approach should work:
var response = o.responseText;
var snode = document.createElement("script");
snode.innerHTML = response;
document.body.appendChild(snode);