Firefox extension interacting with the DOM - javascript

May be my logic is wrong but I'm trying to send and receive datas between my extension and the content.
So I start with something like this to send data from my content to my extension :
var images_elements = [];
tabs.activeTab.attach({
contentScript: "postMessage(document.getElementsByTagName('img'));",
onMessage: function (message) {
images_elements = message;
}
});
Obviously, it doesn't work.
How can I do something like this ? And How can I did it in the other way, example make something on this elements after making a require("sdk/request").Request and replace them in the content.

You can send data, but the API accept only data that is JSON-serializable value.
DOM nodes are not in that category, that's why it doesn't work.

Related

AppMaker Error: "SEVERE: Failed due to circular reference." when I try to run server script for "query.sorting" a table

I'm setting up a google-app-maker app. I want to sort a table with a query.
I want to call a script onAttach-Event. Because I need to user the "query" to sort my data, I have to use a server script. In google-app-maker i can't use a query at client script, right?!
But every time I try to call the server script I get an error
SEVERE: Failed due to circular reference
onAttach Event:
google.script.run.withSuccessHandler(function () {
}).sortTable(widget);
The server script:
function sortTable(widget) {
}
I have already a worked server script. This works perfect. I call this from "App startup script" like:
google.script.run.withSuccessHandler(function(reValue) {
...
}).initUserData(startCode);
Server script here:
function initUserData(startCode) {
...
}
The query looks like:
function sortTable(widget) {
var people = widget.parent.datasource.relations.People;
var query = people.newQuery();
query.sorting.PeopleRole._descending();
// query.sorting.Name._descending(); // sorted by people.Name
var records = query.run();
app.saveRecords([records]);
...
}
Based on your comment I would suggest editing your query script for the datasource itself. You can find your datasource settings as depicted in the attached image, you would need to change it to server script vs query builder and then put the following code in there:
query.sorting.peoplerole._descending();
return query.run();
I simple user javascript sort() now.
I call a client script:
function sortTable(widget) {
var peopleOfComplany = widget.parent.datasource.relations.PeopleOfComplany.items;
peopleOfComplany.sort(function(a, b) {
return b.PeopleRole - a.PeopleRole;
});
}
it works perfectly.
But now i have to figure out how to sort, when PeopleRole is an array.

Exchanging data between content and injected script

I am trying to have a function in an injected script which gets some paramaters and forwards them to the content script, which in turn forwards it to the background script. I have read Chrome extension - retrieving Gmail's original message, but applying that code does not work properly. I have the following code which is injected.
window.postToContentScript = function(cmd, payload) {
var obj = {"command": cmd, "data": payload};
console.error(obj);
document.dispatchEvent(new CustomEvent('MyCustomEvent', {
detail: obj,
}));
}
When called, it logs my passed parameters to the console (so that's not an issue..). In the content script, I have the following code:
document.addEventListener("MyCustomEvent", function(e) {
console.error(e);
})
I would guess that it should actually contain an object with properties command and data, however the detail property of the event is just null. I realize that one way of approaching this is to add e.g. a hidden textarea into the document, filling that and subsequently reading it from the content script. However, this hardly seems as elegant as appending details to an event..
Any thoughts?

How to handle multiple AJAX behaviors in one HTTP request?

I am using jQuery. I have implemented a multipart web page where a list of links* are rendered and each link is periodically updated through AJAX HTTP requests. That is, on the page there are many links of which each one is "timer-triggered" through JavaScript so to perform a HTTP request to the URL pointed by the link itself and, on response success, to replace those links with the retrieved data (the updated links).
This implementation works but it is "performance less" in cases when the page contains many links: one AJAX request is executed per link resulting in many hits to the server. In order to solve that performance issue I thought to make the JavaScript code to execute a unique AJAX request that retrieves the whole set of links and then to replace DOM data.
However I do not know how to implement the "unique request" mostly due to the practice/technique that I have to use and since it is the first time I notice this kind of problem. What can I do? Should I implement a JavaScript handler for event-registration or what?
* In my case link elements are used (<a></a> HTML tags) but those can be anything associated with a URL.
Update after the jfriend00 answer
If the solution is to build a JSON array as jfriend00 describes in his answer then I should implement the page behavior so to update the JSON array dynamically. Since my HTML links are even rendered dynamically along with some JavaScript code then that JavaScript code could update the JSON array dynamically by "registering"/"unregistering" links. If this is a solution in my case, how can I implement it?
I render links as "partial templates" along with the JavaScript code which JavaScript makes those links to execute AJAX requests. HTML-JS code per each link (the mentioned "partial templates") looks like the following:
<script type="text/javascript">
(function() {
var link = $('#link_1')
...
}());
</script>
It seems like you can just send some JSON that is your array of links to request and then receive JSON back that is an object where each key is the requested link and the data is the server response for that particular link.
If the links you want to process look something like this:
<a class="myLink" href="xxx"></a>
It could look something like this:
function processLinks()
// assuming you can specify some CSS selector to select the links in your page that
// you want to target
// create an array of URLs for the ajax call
// and an index of arrays --> DOM objects so we know which DOM object goes
// with a given URL when processing the ajax results
var urlArray = [];
var urlIndex = {};
var urlArray = $(".templateLink").each(function() {
urlArray.push(this.href);
urlIndex[this.href] = this;
});
$.ajax({
url: "your ajax url here",
data: JSON.stringify(urlArray),
dataType: "json"
}).done(function(data) {
// assumes you get data back as {"url1": data1, "url2": data2, ...}
$.each(data, function(url, urlData) {
// get DOM object that goes with this URL
var domObj = urlIndex[url];
// apply urlData to domObj here
})
});
}
Updating my answer now that you've disclosed your "partial templates".
To process them all at once, change this type of structure which processes them one at a time:
<script>
(function() {
var link = $('#link_1')
...
}());
</script>
<a href="yyy" id="link_2></a>
<script>
(function() {
var link = $('#link_2')
...
}());
</script>
to this which finds them all in the DOM and process them all at once:
<script>
// process all the template links
$(document).ready(processLinks);
</script>

Mutiple tag change within Javascript in HTML

this is my json data
[
{
"menu":
{
"MenuID":"1",
"OmfID":"1",
"menu_name":"Coyote Blues Louisiana Menu",
"menu_description":"Full Menu served all day long. ",
"menu_note":null,
"currency_symbol":"$$",
"language":"En",
"disabled":"0",
"menu_uid":"Lake Charles\u0000\u0000\u0000\u0000",
"menu_duration_name":"All Day",
"menu_duration_time_start":"11:00:00",
"menu_duration_time_end":"11:00:00",
"fDateAdded":"2013-12-20 13:00:44"
}
}
]
this is my javascript
function Menus_RestaurantID()
{
var query = $.getJSON('Menus/RestaurantID.json',function(data)
{
console.log("success");
});
query.error(function (data)
{
alert("error");
});
query.complete(function(data)
{
var h=new String();
var text = $.parseJSON(data.responseText);
//alert("data length equals ");
//alert(text.length);
var t=new String();
t+='<ul class="tabs">';
/*for(var i=0;i<text.length;i++)
{
t+='<li>'+text[i]['menu'].menu_name+'</li>';
}
t+='</ul>';
h+='<div class="panes">';*/
for(var i=0;i<text.length;i++)
{
h+='<div>';
//h+=text[i]['menu'].MenuID+'<br>';
//h+=text[i]['menu'].OmfID+'<br>';
//h+=text[i]['menu'].menu_name+'<br>';
if(text[i]['menu'].menu_description!=null)
h+=text[i]['menu'].menu_description+'<br>';
if(text[i]['menu'].menu_note!=null)
h+=text[i]['menu'].menu_note+'<br>';
h+=text[i]['menu'].currency_symbol+'<br>';
h+=text[i]['menu'].language+'<br>';
//if(text[i]['menu'].disabled!=null)
//h+=text[i]['menu'].disabled+'<br>';
h+=text[i]['menu'].menu_uid+'<br>';
h+=text[i]['menu'].menu_duration_name+'<br>';
h+=text[i]['menu'].menu_duration_time_start+'<br>';
h+=text[i]['menu'].menu_duration_time_end+'<br><br><br><br>';
//h+=text[i]['menu'].fDateAdded+'';
h +='</div>';
}
h += '</div>';
//alert("h");
//alert(h);
$('#menus').append(t);
$('#menus').append(h);
});
$(function()
{
// setup ul.tabs to work as tabs for each div directly under div.panes
$("ul.tabs").tabs("div.panes > div");
});
I'm retrieving the data right but I want to display the information in tab dividers. Like in http://jquerytools.org/demos/tabs/index.htm but as of right now the only thing it does is shows all the data in just one. I'm not sure if its because of how im retrieving the data or what.
My Question is:
Why isn't my code displaying properly?
What is another way to display the data in tabs?
The following line sets up the tabs:
$("ul.tabs").tabs("div.panes > div");
However, that is run when the page loads. At that point your tabs do not exist in the page. You add them later via the ajax request. You need to add that line to the complete callback after you have added the tabs to the page.
Edit:
Bunch of problems here
Your tabs ulis empty since the code that fills it is commented out
You have no connection between the list items (which I guess are meant for the tab header) and the divs containing the tab content (the divs should have an id and the links in the list items should target that id)
You need to call .tabs() on the container containing both the headings and the content, not just the headings
You should be calling .done() not .complete()
You had called $.getJSON so the data returned will be parsed JSON already but you try to parse it again.
I think you might want something like this fiddle. (I have changed to hard-code the var data in the .done() to make it work in the fiddle. In a real use case remove the var data = ... defintion and set data as a paramater to the callback like query.done(function(data){ )
I suggest also re-reading the tabs documentation and using a debugger to see what is sent back and forth when you make ajax requests and what error messages come in the console (my personal preference is for Firebug but Chrome dev tools and fiddler are also options)

Displaying data from a database using jQuery and Javascript

I'm trying to display specific parts of a Cloudant database. This database contains many separate documents, and each document contains a category called "results". I'm trying to display whatever is in results. Each document is identified by its own id. I tried using the get() method in jQuery, but unfortunately it is not running successfully.
function grabData(){
var url = 'https://cloudant.com/futon/document.html?acharya%2Ftoxtweet/ff558f75077e8c758523cd3bd8ffdf88';
$.get(url, function(data) {
$('.result').html(data);
alert("Data loaded: " + data);
});
}
grabData();
I'm not entirely sure where I went wrong...Should I consider using SQL instead of ajax?
I think your issue it this:
replace this:
grabData();
with this:
$(document).ready(function(){
grabData();
});
or more shortened:
$(function(){
grabData();
});
The URL you are using is returning an entire webpage.
Your jQuery code is looking for an element on the current page with a class name of result and trying to change it's inner HTML to the response from the URL.
You didn't provide any additional code to look at, but I would assume that is not what you were expecting it to do.
I assume you are wanting to parse through the entire url, but in your current code the page will be processed as a raw string and not a DOM object. So you would have to parse through that string with regular expressions, etc.

Categories

Resources