I am using jupyter notebook to develop a sort of proof of concept for a project of mine, right now I have the 2 pages loaded in the same iframe in one jupyter notebook cell. Right now I don't know what approach to take to solve the communication between these 2 pages in the same widget.
My 2 pages:
<!DOCTYPE html>
<!-- PAGE 1 -->
<html>
<body>
<button type="button" class="snd_Button">Click</button>
</body>
</html>
---------------
<!DOCTYPE html>
<!-- PAGE 2 -->
<html>
<body>
<h1 class ="Listener">I must react.</h1>
</body>
</html>
As you can see they are quite simple, what I wanted to know is what would be a good approach to communicate between them. I want to make so that when I click on the button of page 1, the text of page 2 dinamically changes.
I am planning on using javascript and searched solutions around it but I am not sure of how to continue, as I am new in JS programming and not familiar with its libraries (I've found some frameowrks like node.js or electron but I am not sure they should be applied here).
HTML doesn't support modifying the contents of another html page in this way. You'll likely need some server-side code to facilitate this.
In your case, I'd recommend using Websockets. There are plenty of youtube tutorials for similar functionality - search "Websockets Chat App" which should give you a good understanding of how to fire an event on one page, and then listen for that event on the second page.
Edit: You mentioned you have two pages rendering inside the same iframe - that doesn't sound right as iframes can only point to a single source.
In the case that you want to interact between an iframe and its HTML parent, maybe using cross-document messaging like this will work
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
So I have just recently started with web design.
My index.html has a menu (consisting of containing links to different pages).
The menu on the index.html page (in a very simplified way, no css and things like that) looks something like this:
<ul>
<li><a class="active" href="index.html"></li>
<li><a href="contactus.html"></li>
<li><a href="help.html"></li>
<ul>
and then there is the content of the page (text, slideshow, images...) - say
<div>
<h1><img><p><script>
</div>
the contactus.html page looks somethinglike this:
<ul>
<li><a href="index.html"></li>
<li><a class="active" href="contactus.html"></li>
<li><a href="help.html"></li>
<ul>
and then there is the content of the page (text, slideshow, images...) - say
<div>
<h1><img2><p><script>
When you click on the link, it leads you to a different page.
So say we have index.html, we click on a link in the menu and it leads us to contactus.html. It changes the page, the contactus.html has to load.
And the question is: is it possible to make it so that the content of contactus.html appears on index.html (and replaces it) but in such a way that does not require another page loading?
I have done some research and found something about innerHTML, but I cannot really understand how to use it. I started with js not a long time ago.
I hope the question somehow makes sense.
Thanks a lot for your suggestions and advice.
Yeah. document.body.innerHTML = "<p>Some new HTML!</p>". And there are lots of other ways as well. I like React, but it definitely has a learning curve. I don't know if real web developers still use jQuery, but it makes a lot of DOM manipulation stuff pretty easy. Good luck!
What server do you use? Do you use apache or ngnix for the html files?
You can get the content of "Contacts.html" and replace the content's html with it.
For example:
$.get("contacts.html", function(data, status){
document.getElementById("content").innerHTML = data;
});
This code uses jQuery for ajax requests and you can use XMLHttpRequest with only javascript.
Caution: You shouldn't run the html only. This will not work without html server.
Cheers.
This will be an extremely simplistic answer because it is a huge argument... but lets start with some basics.
The objective is, starting from a web page (index.html), to load some content and update only part of the content in the current page.
I will suggest two different approaches for both client and server side of the equation.
jQuery + HTML fragments
The idea of this approach is to use jQuery to manage AJAX requests to retrieve some content from the server and to update the DOM of the current page to display the new content.
Server side
Here you need to expose some content, in the simplest of cases it can be just a fragment of html like this:
fragment.html
<p>My asynchronously loaded content!<p>
The fragment above can be exposed directly as static content through apache or nginx, or can be generated dynamically with PHP, Java, C# or any programming language with good support for web development.
Client side
On the client we want to contact the server from javascript and retrieve the content with an AJAX request, then update the html. jQuery enables us to do both of those things.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test page</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</head>
<body>
<h1>Home page</h1>
<div id="content">
<p>Welcome!</p>
</div>
<div>
<button id="update-btn">Update content</button>
</div>
<script>
$(document).ready(function() {
$('#update-btn').click(function(){
$.get('http://myserver/fragment.html').then(function(data) {
$('#content').html(data);
});
});
});
</script>
</body>
</html>
We have a div with id content which we will use as the target for the new content, and a button with id update-btn to launch the request.
In the <script> block we first associate the click event to the button so that when clicked we send an ajax request to the server using jQuery get method and update the html content with jQuery html method.
Javascript framework + REST API
This is definitely a more complex approach and a complete guide/example is out of scope for a SO answer (there are books hundreds of pages long for each client side framework and for each server side language/framework) but let's explore the base concept behind this idea.
In the previous example we had the server generate an html and then the client ask for more html to update itself. Here the basic idea is the same but with a much more clear separation of concerns where the server is in charge of generating and sending raw data to the client (usually in JSON or XML format), and the client has to manage all of the presentation and user interaction aspects.
As an example we can analyze the hacker-news get item api.
The url structure is https://hacker-news.firebaseio.com/v0/item/{item-id}.json?print=pretty
We can make a GET request with a an id as a path variable and an optional query parameter called print and it will return some JSON data.
For example we can curl https://hacker-news.firebaseio.com/v0/item/25213368.json?print=pretty and get the following response:
{
"by" : "harporoeder",
"descendants" : 8,
"id" : 25213368,
"kids" : [ 25224137, 25224226, 25224397 ],
"score" : 31,
"time" : 1606333258,
"title" : "Use `nproc` and not grep /proc/cpuinfo",
"type" : "story",
"url" : "https://www.flamingspork.com/blog/2020/11/25/why-you-should-use-nproc-and-not-grep-proc-cpuinfo/"
}
Once we have all the services we need exposed the client can be built with many different frameworks and libraries. In the first approach we used jQuery which is fine for very simple use cases but can become a hell to write and maintain when we start adding complexity to our application, this is why there are many different frameworks to implement the client such as: VueJS, React, SvelteJS, Angular, Aurelia and many others.
Each one of those javascript frameworks has a big learning curve and you will most probably also need to learn how to work with Nodejs, NPM, transpilers and bundlers to make use of the whole modern javascript infrastructure.
This will not be an easy journey but you will learn a valuable skill if you decide to go this road.
Hope this gives you an idea on how to go on with learning web development.
This is your answer with vanilla javascript.
index.js file is:
onclick = "changeHtml()";
const button = document.getElementById("btn");
button.addEventListener("click", function () {
document.getElementById("app").innerHTML = `
<h1>I'm another HTML</h1>
<div >
<p>Look at me</p>
</div>
`;
});
and index.html file is:
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<h1>Hello Vanilla!</h1>
<div>
<p>This is initial HTML</p>
<button id="btn">Click Me!</button>
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
You can change the content of any tag in HTML. like <body>, <a>, etc.
I am building a very simple 5 question multiple choice quiz "game" that just asks 5 simple questions displayed using HTML radio buttons, and a JavaScript function that validates if the user's selection is correct, and iterates a "score" which, when the submit button is clicked, displays "You got X out of X correct." Basically a .js 101 project.
I'm using a Content Management System called Blackbaud Internet Solutions (BBIS). It is proprietary to Blackbaud, and allows the user to build a fully functioning website that integrated with Blackbaud's CRM database. It allows you to build layout using HTML, however in the built-in HTML editor you do not declare any !DOCTYPE or <body> or <head> tags, you just start with your first or whatever, and the system will build out each page using it's native .aspx functionality.
BBIS does have a sophisticated stylesheet section that allows you to create and stack .css, however JavaScript is not handled in the same way.
A web developer that wants to include JavaScript on a page must insert that script by creating what BBIS calls an "Unformatted Text Part." (a "part" is like a widget, or block etc.) The Unformatted Text Part allows you to insert whatever you have between <script> ... and ...</script> in the:
<head>
<body>
at the end of the <body>
Locally on my workstation the .html, .css, and .js files all work together perfectly. And in BBIS, the HTML renders great, the CSS looks good, however, the JavaScript aspect just doesn't work at all. When you click the submit button, the screen flashes and the form's 5 radio buttons just reset to unselected.
Using Chrome's developer tools I can see in the DOM that the CMS (BBIS) brings a whole lot of unnecessary JavaScript to the party. I'm sure that on a page with more elements, these scripts have a perfectly logical function. But this page is literally a white background with nothing but a quiz in the middle of the page. My onSubmit button function has 3-4 other "onSubmit" scripts running on the same page, and I cannot help but think that this is the problem.
In the DOM, I can see that my JavaScript function has been inserted into the <head> tag, because that is where I configured it to load inside of the BBIS "unformatted text part". All the native BBIS "onSubmit scripts" appear in the <body>. Is there a way that I can insert some JavaScript into the <head> that will "take out" those <body> BBIS "onSubmit" scripts?
when you get a blank page maybe you leave the CMS page on submit?
How does your html form look like?
Another thing is, are you using jquery? Most CMS bring their own version of jquery. Try to use jquery in no conflict mode https://api.jquery.com/jquery.noconflict/
Edit the unformatted text part, and select the 'advanced options' button. You can choose to drop your part in the <head> from there.
So I work with a very small business and I am working on shared contact database in Google Sheets. One of the things I would like to include is a simple button (I just used a drawing I made in Sheets) that says "Add New Contact" and when clicked it opens up a Google Form I created that will collect the contact info and store in it the Google Sheet.
My question is... What Google app script can I use to achieve that task? I'm very new to Google Apps script so I don't really know how to go about writing the code properly.
Thanks for your answers!
I just want a Simple Button!
The easiest way to create a button is to create a new html file in the script editor. When you do, it will open up a file and ask for a name. You add the name "AddNewContent" and look in the file and it will have this content.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
</body>
</html>
Add content so that it looks like this:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function addNewContent()
{
google.script.run.addNewContent();
}
</script>
</head>
<body>
<input id="btn0" type="button" value="Add New Contact" onClick="addNewContact();" />
</body>
</html>
Now go to the Code.gs file. When you start a new project the Code.gs file is added automatically and it contains the following:
function myFunction(){
}
Replace the code with this:
function addNewContent()
{
}
Now you have a button that's connected to the shell of a Google Apps Script Function. To display the button on a sidebar you can create another function in the Code.gs file like the one below:
function showSideBar()
{
var userInterface=HtmlService.createHtmlOutputFromFile('AddNewContent');
SpreadsheetApp.getUi().showSidebar(userInterface);
}
And then to display the sidebar easily you can add the showSideBar function to a menu which will be created whenever you open your spreadsheet.
function onOpen()
{
SpreadsheetApp.getUi().createMenu('My New Menu').addItem('Display my Sidebar', 'showSideBar').addToUi();
}
So if you save all of those files and select the onOpen function in the code editor so that the menu looks like the image below and press the triangular button then it will run the onOpen function and you won't have to close and reopen the program to get it to run and the menu will magically appear on the spreadsheet. Now you can display your side bar and run your Google Apps Script function.
Unfortunately, the function doesn't do anything yet because I don't actually know what you want to do or have down. If you already created a Google Form then it has already linked itself to a spreadsheet and it's already collecting data. If you have created an HTML form of your own (which is doubtful) then you can display it as a dialog or deploy it as a web app.
So the real question is what have you done and where do you want to go from here. Unfortunately, writing Google Apps Script requires a fair knowledge of Javascript, HTML, a little CSS and in my case a bit of JQuery. It also involves a far amount of reading and research. And while you may not believe it now. Most of the questions I had about Google Apps Script are found in the documentation. Which is where I'd recommend that you go and read and then reread again and again until you know where to find everything you need to write your scripts. Most of the time when I need something I can find it in a Google Search and very often it will bring me right back to this site. But many of the answers to questions involve a fair amount of learning on my part.
The first time I tried to learn Google Apps Script was in 2009 and I finally gave up because I just got lost looking for documentation. But about 10 months ago I took another look and really liked what I saw in terms of how the documentation was organized so I jumped in again. A couple of months later I started visiting StackOverFlow.com and then I answered a few questions here and there and now about 8 months later I feel pretty good about many spreadsheet related tasks. I'm still weak in several areas and hanging around this site helps to remind me of all the things I could be learning.
I´m starting to develop a Chrome App just to test it.
It seems that this kind of applications (desktop app at the end) must be developped with the single-page concept in mind.
But my application consists of three pages or "sections": One to control a web-cam, another to watch a streaming and the last to control a videoconference.
I´ve been reading and coding a bit within the Chrome Platform developing center, and just could find basic tutorials with one .html page.
So, my question is: What is the best way to load different .html pages (because i need to show different UI sections) in a Chrome App? I´ve seen that Google uses AngularJS to implement an MVC pattern, but i don´t know how to change from one view to another (thinking of views as .html pages) in that scenario (because i´ve never used AngularJS).
Thanks!
Is there a specific reason you need multiple HTML pages? It's pretty straightforward to do something like this:
<html>
<body>
<div id="tab_1">Section One</div>
<div id="tab_2">Section Two</div>
<div id="tab_3">Section Three</div>
</body>
</html>
and then show/hide each div according to which part of your app you want to show. CSS frameworks like Bootstrap are designed to work well this this kind of approach, turning the set of divs into a pane with a left nav, or a content area with a tab strip, all of which match the needs of a typical app UI.
I have used $.mobile.changepage to do the redirect in my phonegap+jquerymobile projects. However what makes me confused is that I need to put the script of all the pages to the same file index.html. If not, the redirect page can not execute the function in its header.
for example, my index.html seem to be
$(document).bind("deviceready",function(){$.mobile.changepage("test.html");})
then, my device will redirect to test.html which seem to be
$("#btnTest").click(function(){alert("123");})
<button id="btnTest">Test</button>
However, the script will never execute in test.html. Then I put the script to index.html, what I expect to be is done. Whatever, if I put all the script to the same page, the project will become harder and harder to be preserved. Appreciated for your help.
Intro
This article can also be found HERE as a part of my blog.
How jQuery Mobile handles page changes
To understand this situation you need to understand how jQuery Mobile works. It uses ajax to load other pages.
First page is loaded normally. Its HEAD and BODY is loaded into the DOM, and they are there to await other content. When second page is loaded, only its BODY content is loaded into the DOM. To be more precise, even BODY is not fully loaded. Only first div with an attribute data-role="page" will be loaded, everything else is going to be discarded. Even if you have more pages inside a BODY only first one is going to be loaded. This rule only applies to subsequent pages, if you have more pages in an initial HTML all of them will be loaded.
That's why your button is show successfully but click event is not working. Same click event whose parent HEAD was disregarded during the page transition.
Here's an official documentation: http://jquerymobile.com/demos/1.2.0/docs/pages/page-links.html
Unfortunately you are not going to find this described in their documentation. Ether they think this is a common knowledge or they forgot to describe this like my other topics. (jQuery Mobile documentation is big but lacking many things).
Solution 1
In your second page, and every other page, move your SCRIPT tag into the BODY content, like this:
<body>
<div data-role="page">
// And rest of your HTML content
<script>
// Your javascript will go here
</script>
</div>
</body>
This is a quick solution but still an ugly one.
Working example can be found in my other answer here: Pageshow not triggered after changepage
Another working example: Page loaded differently with jQuery-mobile transition
Solution 2
Move all of your javascript into the original first HTML. Collect everything and put it inside a single js file, into a HEAD. Initialize it after jQuery Mobile has been loaded.
<head>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<script src="index.js"></script> // Put your code into a new file
</head>
In the end I will describe why this is a part of a good solution.
Solution 3
Use rel="external" in your buttons and every elements you are using to change page. Because of it ajax is not going to be used for page loading and your jQuery Mobile app will behave like a normal web application. Unfortunately this is not a good solution in your case. Phonegap should never work as a normal web app.
Next
Official documentation, look for a chapter: Linking without Ajax
Realistic solution
Realistic solution would use Solution 2. But unlike solution 2, I would use that same index.js file and initialize it inside a HEAD of every possible other page.
Now you can ask me WHY?
Phonegap like jQuery Mobile is buggy, and sooner or later there's going to be an error and your app will fail (including loaded DOM) if your every js content is inside a single HTML file. DOM could be erased and Phonegap will refresh your current page. If that page don't have javascript that it will not work until it is restarted.
Final words
This problem can be easily fixed with a good page architecture. If anyone is interested I have wrote an ARTICLE about good jQuery Mobile page architecture. In a nut shell I am discussing that knowledge of how jQuery Mobile works is the most important thing you need to know before you can successfully create you first app.
Unlike normal ordinary HTML pages, jQuery Mobile uses ajax technology when navigating between pages. So make sure to import all your JS files and libraries in all your html pages.
If you notice closely you will see that JS files from previous page is taken into consideration when loading the second page. But if you force rrefresh the current page then the js files of the current page will be effective.
So as I said earlier make sure to import the js files in all the html files.
Also no need to call deviceready, use following syntax to call your page specific js functions
$(document).on('pageshow', '#YourPageID', function(){
// Your code goes here
});
Jquery Mobile uses ajax to load a "page". A "page" here is a div with data-role=page. If you load a physical page index.html, you can navigate using changePage to any "page" div inside that page.
However, if you want to load a "page" from other physical page, jQM will only load the first "page" div from that page. What actually happen is you do not change page, jQM just load that particular "page" div using ajax and inject it to your current page.
You have two possible architecture where you put all your "pages" in a html page and navigate from there. Or you can have multiple page architecture. You can always mix this.
To physically change page, you need to add rel=external to your link.