this is my first question on StackOverflow and my first time working with Chrome Extensions.
I am trying to get user input from an html popup and use jquery to pass that input to a javascript function. The openNewPopup function works here, and the removeATab function works only if I hard code a specific tab index within the function (not passing in the index).
My background.js
function openNewPopup() {
chrome.tabs.create({
index: 0,
url: "http://google.com"
}, function(tab) {
console.log(tab);
});
}
function removeATab(removeTab) {
chrome.tabs.query({currentWindow: true}, function(tabs) {
lastTabId = tabs[removeTab].id;
chrome.tabs.remove(lastTabId);
});
}
My popup_script.js
document.addEventListener("DOMContentLoaded", function() {
var backgroundPage = chrome.extension.getBackgroundPage();
document.querySelector('#newTabButton').addEventListener('click',
function() {
backgroundPage.openNewPopup();
});
document.querySelector('#btnRemove').addEventListener('click',
function() {
var indexRemove = document.querySelector('#tabRemove');
backgroundPage.removeATab(indexRemove);
});
});
And my popup.html
<!DOCTYPE html>
<html>
<head>
<title>Work with tabs</title>
<script src="popup_script.js"></script>
</head>
<body>
<h3>"Open new tab"</h3>
<button id="newTabButton">Make a new tab!</button>
<div class="remove">
Remove tab:<br>
<input type="number" name="tabRemove" id="tabRemove">
<br>
<input type="button" id="btnRemove" value="Remove">
</div>
</body>
</html>
Related
I'm trying to create a watch-later extension for Google Chrome. This means, if I press a button that is in the extension, it saves the URL and the title of the web and shows it down of the button. If I press it, it redirects me to that URL.
The extension is working perfect if I save only a URL. But I want to save more than one. I think I should use an array, but I don't know how to implement it in this case.
What's wrong on this code? Thanks for your attention!
chrome.storage.sync.get(["activeTab", "nameOfTheTab"], function(items){
var item = items.activeTab;
document.getElementById('urlDude').href = item;
document.getElementById('urlDude').innerHTML = items.nameOfTheTab;
});
saveItem.onclick = function(element) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0].url;
var totalTabs = [];
totalTabs.push(activeTab);
var tabName = tabs[0].title;
chrome.storage.sync.set({ "activeTab": totalTabs }, function(){ });
chrome.storage.sync.set({ "nameOfTheTab": tabName }, function(){ });
document.getElementById('urlDude').href = tabs[0].url;
document.getElementById('urlDude').innerHTML = tabName;
});
};
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./popus.css">
</head>
<body>
<button id="saveItem">save</button>
<script src="popup.js"></script>
<br>
<br>
<a id="urlDude" target="_blank"><p>Hola</p></a>
</body>
</html>
i need to make it so that when a zip code is typed into the box and the submit button is clicked, the name of the city shows up under it. when i click the button after putting a zip code the city name doesn't show up. it says the error is that wallOfText is not a function but i'm not sure how to fix it. any help would be appreciated!! here's the code:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
Enter your zip code:<br><input type="text" id="zipBox" name="zipCode"><br><br>
<button onclick="weatherFunction()">Submit</button>
<p id="result"></p>
<script>
function weatherFunction() {
var zip = document.getElementById("zipBox").value;
jQuery(document).ready(function ($) {
$.ajax({
url: "http://api.openweathermap.org/data/2.5/weather?zip=" +zip+ ",us&appid=b3456f9acbfa64fc4495e6696ecdc9a5",
dataType: "jsonp",
success: function (wallOfText) {
city = wallOfText("name");
if (zip != null) {
document.getElementById("result").innerHTML = wallOfText;
}
}
});
});
}
</script>
</body>
</html>
The issue you have is that you're attempting to call wallOfText like it's a function, when in fact it's the object which has been deserialised from the response of the AJAX call. As such, you need to access the object's name property to set the city variable, then use that to set the text() of the #result element.
Note that the document.ready handler within the function is redundant, and you should be doing the zip value validation before you make the request. I also updated the logic to use jQuery to bind the event handler on the button instead of the outdated onclick attribute. Try this:
jQuery(function() {
$('#send').click(function() {
var zip = $("#zipBox").val();
if (zip !== '') {
$.ajax({
url: "http://api.openweathermap.org/data/2.5/weather?zip=" + zip + ",us&appid=b3456f9acbfa64fc4495e6696ecdc9a5",
dataType: "jsonp",
success: function(wallOfText) {
var city = wallOfText.name;
$("#result").text(city);
}
});
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Enter your zip code:<br>
<input type="text" id="zipBox" name="zipCode" value="90210" /><br /><br />
<button type="button" id="send">Submit</button>
<p id="result"></p>
I want to have a dialog window with an input. I could use the default jQuery-ui one, but I am using one that incorporate bootstrap. However, the input only appears the first time that it is opened, any subsequent times the dialog is opened, the input is missing. How would this be remedied?
Here is the HTML:
<!DOCTYPE html>
<html>
<head lang="en">
<link rel="stylesheet" href="../bower_components/jquery-ui/themes/base/jquery.ui.all.css">
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../bower_components/bootstrap3-dialog/css/bootstrap-dialog.min.css">
<link rel="stylesheet" href="../bower_components/bootstrap-datepicker/css/datepicker3.css">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>Hello!</h3>
<div>
<span>Enter a Zip Code: </span>
<input type="text" id="zip">
<button id="getEvents" class="btn btn-primary">Get events!</button>
</div>
<div class="datepicker"></div>
<div id="events"></div>
<button id="addItemButton">Add an item</button>
<div id="addItemDialog"><input type="text" id="newItem"></div>
<script src="../bower_components/jquery/jquery.min.js"></script>
<script src="../bower_components/jquery-ui/ui/jquery-ui.js"></script>
<script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="../bower_components/bootstrap3-dialog/js/bootstrap-dialog.js"></script>
<script src="../bower_components/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
<script src="js/calendar.js"></script>
</body>
</html>
Here is the JS:
$(function () {
"use strict";
var url,
year,
month,
zip,
date,
events = [],
newItem;
$("#addItemDialog").hide();
$(".datepicker").datepicker({dateFormat: "yy-mm-dd"}).click(function(){
$("#events").empty();
date = $(".datepicker").datepicker("getDate");
//console.dir(date.toISOString().substr(0, 10));
$(events).each(function(i, event){
//console.log(event);
if(event.date.substr(0, 10) === date.toISOString().substr(0, 10)){
console.log(event.title);
$("#events").append("<h4 class='event'>" + event.title + "</h4>");
}
});
});
$("#getEvents").on("click", function () {
zip = $("#zip").val();
if(isValidUSZip(zip)){
zip = zip.substr(0, 5);
getCalendar();
}else{
BootstrapDialog.show({
message: "You must enter a valid zip code!",
buttons: [{label:"OK", action: function(dialog){dialog.close();}}],
draggable: true
});
}
});
function isValidUSZip(sZip) {
return /^[0-9]{5}(?:-[0-9]{4})?$/.test(sZip);
}
function getCalendar() {
$.ajax({
type: "GET",
url: "http://www.hebcal.com/hebcal/?v=1&cfg=json&nh=on&nx=on&year=now&month=x&ss=on&mf=on&c=on&zip=" + zip +"&m=72&s=on",
success: function (data) {
console.dir(data);
$(data.items).each(function(index, item){
//console.dir(item.date.substr(0, 10));
events.push(item);
});
}
});
}
$("#addItemButton").on("click", function(){
BootstrapDialog.show({
message: $("#newItem"),
buttons: [{
label: "Enter",
action: function(dialog){
newItem = $("#newItem").val();
events.push({date: new Date(date).toISOString(), title: newItem});
dialog.close();
}
}]
});
});
});
I took a time and make this fiddle, aparently everything is working fine:
I doubt about this line for a moment, but still uncommented is going right:
$(function () {
//"use strict";
var url,
year,
month,
zip,
date,
events = [],
newItem;
http://jsfiddle.net/r2FyC/3/
Using the sample below, I have a tr that I am duplicating. It contains a jQuery autocomplete. The first time it is cloned, the auto complete functionality does not work because the attached data("items") is null. The second time the Add button is clicked, the autocomplete works. Thereafter, clicking Add once again produces a non-functioning autocomplete.
Adding a breakpoint inside of the makeAutoComplete function shows that items is always null except for when clicking Add the second time!
Can anyone explain this strange behavior?
HTML/JS (Fiddle here: http://jsfiddle.net/SDvF4/12/)
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Test!</title>
<style type="text/css">
tr.Template
{
display: none;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.8.18/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function ()
{
var textbox = $(".AutoComplete");
makeAutoComplete(textbox);
$("#addButton").click(function ()
{
var attrRegex = /\d+/;
var template = $("tr.Template");
var newRow = template.clone(false);
var newRowIndex = (template.siblings().length + 1);
newRow.removeClass("Template");
newRow.find("*[id]").each(function ()
{
var element = $(this);
element.attr("id", element.attr("id").replace(attrRegex, newRowIndex));
});
newRow.find("*[name]").each(function ()
{
var element = $(this);
element.attr("name", element.attr("name").replace(attrRegex, newRowIndex));
});
newRow.insertBefore(template);
newRow.find(".AutoComplete").each(function ()
{
makeAutoComplete($(this));
});
});
});
function makeAutoComplete(textbox)
{
var items = textbox.data("items");
var test = textbox.data("test");
if (items == null)
{
if (test == "JSM")
alert("ERROR: data.items not copied but data.test was!");
else
alert("ERROR: data.items not copied nor was data.test!");
}
textbox.autocomplete(
{
minLength: 0,
source: items
});
}
</script>
</head>
<body>
<table>
<tbody>
<tr class="Template">
<td>
<input id="test_0" name="test_0" class="AutoComplete" type="text"/>
<script type="text/javascript">
var testData = [{ label: "One", value: 1 }, { label: "Two", value: 2 }];
$("#test_0").data("items", testData);
$("#test_0").data("test", "JSM");
</script>
</td>
</tr>
</tbody>
</table>
<br/><br/>
<button id="addButton">Add</button>
</body>
</html>
There were multiple issues I had to fix to get this to work.
First was pointed out by #pimvdb - I wasn't IDing the elements correctly so the second new row had the same ID as the template row.
Second, you can't simply call autocomplete on a widget that is already an autocomplete - first you have to destroy it:
textbox.autocomplete("destroy");
textbox.removeData("autocomplete");
The 12th revision works correctly: http://jsfiddle.net/SDvF4/12/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.js"></script>
</head>
<body>
<form id="fooForm">
<script type="text/javascript">
function FooMethod() {
alert('hello');
}
var fooButton;
var fooForm;
var fooDialog;
$(document).ready(function() {
InitializeVariables();
InitiliazeDialog();
InitiliazeForm();
});
function InitializeVariables() {
fooButton = $('#fooButton');
fooForm = $('#fooForm');
fooDialog = $('#fooDialog');
}
function InitiliazeDialog() {
var dialogOpenMethod = function () {
fooDialog.dialog('open');
return false;
};
var submitMethod = function () {
fooButton.unbind('click', dialogOpenMethod);
fooButton.click();
};
fooDialog.dialog({
autoOpen: false,
modal: true,
buttons: {
'Ja': submitMethod,
'Nein': function () {
fooDialog.dialog('close');
}
}
});
fooButton.bind('click', dialogOpenMethod);
}
function InitiliazeForm() {
fooButton.button();
fooForm.submit(function () {
alert('doing a submit');
});
}
</script>
<input type="submit" id="fooButton" value="submit it!" onclick="FooMethod();"></input>
<div id="fooDialog">
Dialog info
</div>
</form>
</body>
</html>
what am i doing?
i want a modal-confirmation: user clicks on button, confirmation "do you really want to...?", user clicks "yes", this click unbinds the original click-handler and clicks the button again (which should cause a submit).
what/why is not working?
indeed you need a special case. this demo won't work, unless you set modal: false.
interesting to mention: the original handler (onclick="FooMethod();") is called in modal and non-modal dialog.
EDIT:
i adapted my sample due to graphicdivines answer, to the following:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.js"></script>
</head>
<body>
<form id="fooForm" method="POST" action="">
<script type="text/javascript">
var fooButton;
var fooForm;
var fooDialog;
$(document).ready(function() {
InitializeVariables();
InitiliazeDialog();
InitiliazeForm();
});
function InitializeVariables() {
fooButton = $('#fooButton');
fooForm = $('#fooForm');
fooDialog = $('#fooDialog');
}
function InitiliazeDialog() {
var dialogOpenMethod = function () {
fooDialog.dialog('open');
return false;
};
var submitMethod = function () {
fooButton.unbind('click', dialogOpenMethod);
fooButton.click();
};
fooDialog.dialog({
autoOpen: false,
modal: true,
buttons: {
'Ja': submitMethod,
'Nein': function () {
fooDialog.dialog('close');
}
}
});
var dialogZ = fooDialog.dialog('option', 'zIndex');
fooButton.bind('click', dialogOpenMethod);
}
function InitiliazeForm() {
fooForm.submit(function () {
alert('doing a submit');
});
}
</script>
<input type="submit" id="fooButton" value="submit it!" style="z-index: 9999;"></input>
<div id="fooDialog">
Dialog info
</div>
</form>
</body>
</html>
why?
as you can see here, there's a nasty z-index-checker which i tried to avoid. but it wont' work.
Seems to me that you need to close the dialog, before you re-click the submit. Since modal disables everything on the page, the dialogue must be closed or the submit is not clickable. So your submit method becomes:
var submitMethod = function () {
fooDialog.dialog('close'); // add this line ==============
fooButton.unbind('click', dialogOpenMethod);
fooButton.click();
};
Why are you not specifying HTML form method? The default form method is GET.
So you should have:
<form id="fooForm" method="post" action="">
Action can be something else, it depends on what URL your submission handling logic is.
Edit:
Also instead of clicking the submit button, just submit the form directly.
fooDialog.dialog({
autoOpen: false,
modal: true,
buttons: {
'Ja': function() { $('#fooForm').submit(); },
'Nein': function () {
fooDialog.dialog('close');
}
}
});