I am working with Next.js. Suddenly I realized that hot reload is not working. Instead, with any changes in the page elements, the page would be fully refreshed, not hot reload.
Let say that there is a file in pages folder called test.js. The content of test.js is as follows:
function test() {
return <div>Test <div>;
}
export default test;
the above code simply, output a simple test message in the page when visiting a local url like this: http://localhost:3000/test .
When I change the test text into something else such as test2, I expect that I should see the new change (test2) instantly in the page (hot reload), but unfortunately the page fully reloads first, and then I can see the new changes in the page (in this example, the new test2 text). This is bothers me so much to wait to see the changes by page refreshing, not by hot reload.
How I can tell Nex.js, not to fully reload the page with any change in page element, but instantly show them on the page, as it is expected ??
The console log message is as follows:
Related
I cannot seem to get Chrome to pop up an "alert" page. The alert page has code in it, so it can't really be a DIV or I would just do it that way. It worked for many years, but likely do to a Chrome update it will no longer function. Still works fine in IE11, though.
The following code is used to pop up an "alert" page when there is an alert that is queried from a Database. It has always worked until recently (15 years and running)
CODE:
ClientScript.RegisterStartupScript(GetType(Page), "Alarm", "<script language='javascript'>window.showModalDialog('Alarm.aspx?ID=" & AlarmID & "', null, 'dialogWidth=460px;dialogHeight=310px;status=no;resizable=yes');document.frmA.submit();</script>")
I've tried a few things like windows.open and creating a hidden button on the asp.net page and then using the click event. Nothing works. I do not see a blocked popup in Chrome and I have even went into settings and did the following:
Set Safe Browsing to "No Protection"
Set allow pop-ups and redirects on the server name (http://servername and http://localhost)
As noted, near all browsers quite much have clamped down on popup windows. this makes things more difficult for web developers.
There are two good approaches. one I don't fancy at all is using bootstrap dialogs, but they tend to "sort of work all on their own" kind of deal based on class settings for divs etc. - really hard to debug.
Since near all sites these days include jQuery for your js code, then I quite much hands down recommend you introduce jquery.UI. It has a whole slew of nice things such as date pickers etc. But it also has a rather nice dialog pop option. They just work, and when you code them up? They follow "normal" like code approaches.
it not quite clear if your message/dialog pops after say a button click (and post back), and the at the end of that process, you need/want some dialog message to display. But all in all, I would high recommend jQuery.UI for this dialog/message that you need.
jQuery.UI in most cases expects the content you want to "display/pop" exists in a simple div in the current existing page. However, it also works VERY well if you supply the dialog another existing web page. The only REAL big issue to keep in mind? That dialog page you pop cannot handle multiple post-backs. (so, some buttons, or ONE post back in that dialog is fine - but you ONLY get the ONE post-back.
So, if that page display allows some input, or some interaction and ONLY requires ONE post-back, then jQuery.UI is again great. If that pop page requires several buttons and several post-backs, then you are in for a world of pain and hurt - jQuery.UI dialogs (like most) cannot survive or handle multiple postbacks. Any post-back means the dialog closes (collapses). So in those cases, you have to adopt ajax calls (web methods) if you need/have/want that page to have more then one active post-back button or event.
So, you could have/place a script in even your master page, and little function code stub that your register script can call.
Or, I suppose you could inject the whole script, but the script would look like this:
So, the pop page actualy is SHOVED into a div. So we have a div that "holds" the page.
The jQuery.UI code script then looks like this:
<div id="poppagearea">
</div>
<script>
function showpage() {
var mydiv = $('#poppagearea');
mydiv.dialog({
autoOpen: false, modal: true, title: 'My cool other page', width: '30%',
position: { my: 'top', at: 'top+150' },
buttons: {
'ok': function () {
mydiv.dialog('close');
alert('user click ok');
},
'cancel': function () {
mydiv.dialog('close');
alert('user click cancel');
}
}
});
mydiv.load('Default.aspx');
// Open the dialog
mydiv.dialog('open');
}
So, in above, we loaded "default.aspx" into that dialog and thus displayed it on the page.
So, I would consider jQuery.UI - but it does mean adopting a new js library into your existing project.
The pop page does gray out the full page, and you do get a title bar, and your own ok, cancel button. The above thus looks like this:
So, it does a great job - but as noted, that page can only have one post-back, and it can't be a general working aspx page with lots of buttons and post backs - but it will render and display rather well.
So I would like to be able to have a print button for entries in our database so users can print an entry via a print friendly "form".
My thought was to create a separate page, add labels and have those labels pull the relevant information.
I know I can add the open widget information via this code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.TestPrint);
But I'm running into a few problems:
I can't get the page to open in a new window. Is this possible?
window.open(app.pages.TestPrint);
Just gives me a blank page. Does the browser lose the widget source once the new window opens?
I can't get the print option (either onClick or onDataLoad) to print JUST the image (or widget). I run
window.print();
And it includes headers + scroll bars. Do I need to be running a client side script instead?
Any help would be appreciated. Thank you!
To get exactly what you'd want you'd have to do a lot of work.
Here is my suggested, simpler answer:
Don't open up a new tab. If you use showPage like you mention, and provide a "back" button on the page to go back to where you were, you'll get pretty much everything you need. If you don't want the back to show up when you print, then you can setVisibility(false) on the button before you print, then print, then setVisibility(true).
I'll give a quick summary of how you could do this with a new tab, but it's pretty involved so I can't go into details without trying it myself. The basic idea, is you want to open the page with a full URL, just like a user was navigating to it.
You can use #TestPrint to indicate which page you want to load. You also need the URL of your application, which as far as I can remember is only available in a server-side script using the Apps Script method: ScriptApp.getService().getUrl(). On top of this, you'll probably need to pass in the key so that your page knows what data to load.
So given this, you need to assemble a url by calling a server script, then appending the key property to it. In the end you want a url something like:
https://www.script.google.com/yourappaddress#TestPage?key=keyOfYourModel.
Then on TestPage you need to read the key, and load data for that key. (You can read the key using google.script.url).
Alternatively, I think there are some tricks you can play by opening a blank window and then writing directly to its DOM, but I've never tried that, and since Apps Script runs inside an iframe I'm not sure if it's possible. If I get a chance I'll play with it and update this answer, but for your own reference you could look here: create html page and print to new tab in javascript
I'm imagining something like that, except that your page an write it's html content. Something like:
var winPrint = window.open('', '_blank', 'left=0,top=0,width=800,height=600,toolbar=0,scrollbars=0,status=0');
winPrint.document.write(app.pages.TestPage.getElement().innerHTML);
winPrint.document.close();
winPrint.focus();
winPrint.print();
winPrint.close();
Hope one of those three options helps :)
So here is what I ended up doing. It isn't elegant, but it works.
I added a Print Button to a Page Fragment that pops up when a user edits a database entry.
Database Edit Button code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showDialog(app.pageFragments.FragmentName);
That Print Button goes to a different (full) Page and closes the Fragment.
Print Button Code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.ModelName_Print);
app.closeDialog();
I made sure to make the new Print Page was small enough so that Chrome fits it properly into a 8.5 x 11" page (728x975).
I then created a Panel that fills the page and populated the page with Labels
#datasource.item.FieldName
I then put the following into the onDataLoad for the Panel
window.print();
So now when the user presses the Print Button in the Fragment they are taken to this new page and after the data loads they automatically get a print dialog.
The only downside is that after printing the user has to use a back button I added to return to the database page.
1.
As far as I know, you cannot combine window.open with app.pages.*, because
window.open would require url parameter at least, while app.pages.* is essentially an internal routing mechanism provided by App Maker, and it returns page object back, suitable for for switching between pages, or opening dialogs.
2.
You would probably need to style your page first, so like it includes things you would like to have printed out. To do so please use #media print
ex: We have a button on the page and would like to hide it from print page
#media print {
.app-NewPage-Button1 {
display : none;
}
}
Hope it helps.
1. Here is how it is done, in a pop up window, without messing up the current page (client script):
function print(widget, title){
var content=widget.getElement().innerHTML;
var win = window.open('', 'printWindow', 'height=600,width=800');
win.document.write('<head><title>'+title+'/title></head>');
win.document.write('<body>'+content+'</body>');
win.document.close();
win.focus();
win.print();
win.close();
}
and the onclick handler for the button is:
print(widget.root.descendants.PageFragment1, 'test');
In this example, PageFragment1 is a page fragment on the current page, hidden by adding a style with namehidden with definition .hidden{display:none;} (this is different than visible which in App Maker seems to remove the item from the DOM). Works perfectly...
2. You cannot open pages from the app in another tab. In principle something like this would do it:
var w=window.parent.parent;
w.open(w.location.protocol+'//'+w.location.host+w.location.pathname+'#PrintPage', '_blank');
But since the app is running in frame nested two deep from the launching page, and with a different origin, you will not be able to access the url that you need (the above code results in a cross origin frame access error). So you would have to hard code the URL, which changes at deployment, so it gets ugly very fast. Not that you want to anyway, the load time of an app should discourage you from wanting to do that anyway.
I am following this example https://kadira.io/academy/meteor-routing-guide/content/rendering-blaze-templates
When I click on my links the whole page is being reloaded. Is there any way to load only the template part that is needed and not the whole page?
Edit: Also I noted another problem. Everything that is outside {{> Template.dynamic}} is being rendered twice.
Here is my project sample. https://github.com/hayk94/UbMvp/tree/routing
EDIT: Putting the contents in the mainLayout template and starting the rendering from there fixed the double render problems. However the reload problems happen because of this code
Template.mainLayout.events({
"click *": function(event, template){
event.stopPropagation();
console.log('body all click log');
// console.log(c0nnIp);
var clickedOne = $(event.target).html().toString();
console.log('This click ' + clickedOne);
//getting the connID
var clientIp = null // headers.getClientIP(); // no need for this anymore
var clientConnId = Meteor.connection._lastSessionId;
console.log(clientIp);
console.log(clientConnId);
Meteor.call("updateDB", {clientIp,clientConnId,clickedOne}, function(error, result){
if(error){
console.log("error", error);
}
if(result){
}
});
}, // click *
});//events
Without this event attached to the template the routing works without any reloads, however as soon as I attach it the problem persists.
Do you have any ideas why this code causes such problems?
EDIT 2 following question Rev 3:
event.stopPropagation() on "click *" event probably prevents the router from intercepting the click on link.
Then your browser performs the default behaviour, i.e. navigates to that link, reloading the whole page.
EDIT following question Rev 2:
Not sure you can directly use your body as BlazeLayout target layout.
Notice in the first code sample of BlazeLayout Usage that they use an actual template as layout (<template name="layout1">), targeted in JS as BlazeLayout.render('layout1', {});.
In the tutorial you mention, they similarly use <template name="mainLayout">.
That layout template is then appended to your page's body and filled accordingly. You can also change the placeholder for that layout with BlazeLayout.setRoot() by the way.
But strange things may happen if you try to directly target the body? In particular, that may explain why you have content rendered twice.
Original answer:
If your page is actually reloaded, then your router might not be configured properly, as your link is not being intercepted and your browser makes you actually navigate to that page. In that case, we would need to see your actual code if you need further help.
In case your page does not actually reload, but only your whole content is changed (whereas you wanted to change just a part of it), then you should make sure you properly point your dynamic templates.
You can refer to kadira:blaze-layout package doc to see how you set up different dynamic template targets in your layout, and how you can change each of them separately (or several of them simultaneously).
You should have something similar in case you use kadira:react-layout package.
StumbleUpon publishes a Widget script, and documents how to use it to insert a stumbleUpon button (they call it a badge), into a website.
You can generate the markup for a button with their online tool. It looks like this:
<!-- Place this tag where you want the su badge to render -->
<su:badge layout="2" location="http://example.com"></su:badge>
<!-- Place this snippet wherever appropriate -->
<script type="text/javascript">
(function() {
var li = document.createElement('script');
li.type = 'text/javascript';
li.async = true;
li.src = 'https://platform.stumbleupon.com/1/widgets.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(li, s);
})();
</script>
That script element is just a way to delay-load the widgets.js thing. Just from looking at it, I suppose that it works by scanning the document for the <su:badge> elements and replacing them with iframes. The iframes themselves then get their source content from stumbleupon, at a URL like this: http://badge.stumbleupon.com/badge/embed/4/?url=http%3A%2F%2Fexample.com .
The iframe renders visually like this:
The stumbleupon button is the 2nd one. I show the other ones for comparison.
As you can see, the StumbleUpon rendering looks different than all the other guys. SU makes their button look like a "badge" while every other social share widget looks like...uh.... a button.
I'm trying to make the Stumbleupon widget look like a button. I'm pretty sure this is possible. For example, mashable does it (example). Here's what it looks like:
As you can see, the stumbleupon button looks like a button. It's not a badge. Mashable is not using the su:badge thing - they have rendered their own <a> tag, and styled it.
The visual rendering is not a problem; I can figure out how to make a span look like a button, no problem. The problem happens when I click the tag or span. It appears to me that, with the iframe-thing that StumbleUpon uses, it invokes this URL to submit a page for sharing:
http://www.stumbleupon.com/badge/?url=http%3A//example.com/whatever HTTP/1.1
The iframe uses javascript's window.open to request that, and restricts the resizing and so on. This is how it works on mashable. The resulting window looks like this:
This is also what the mashable page does, though it does not use the iframe. The Mashable page contains javascript that just opens the "stumbleupon submit" window directly from within the main mashable page.
But when I try the same thing from my page, the little fixed window gets a 302 redirect from StumbleUpon, and then another 302, which eventually points it to
http://www.stumbleupon.com/submit/visitor
...which does not allow sharing of the link.
This has been a long story, but:
does anyone have any insight as to how I can convince StumbleUpon to let me share a link or URL, from a button that is not contained within an iframe?
What is mashable's secret?
ok here's what I found.
The 302's that eventually pointed me to /submit/visitor happen when both of the following are true:
the user is not logged in
the article has not been stumbled in stumbleupon previously
When that happens, stumbleupon invites you (the user) to login. It won't take you just to the "submit url" page.
If the user is not logged in, but the article HAS been submitted previously, then it takes you to the submit window without a 302. Eventually you will be asked to login, if you proceed with the submission. But the first view of the stumbleupn website in this case gives you a visual indication that you are submitting something.
If the user is logged in, and the article has not been submitted previously, then you get taken right to the submit page.
So I was doing nothing wrong. I just needed to login the first time. This is just an artifact of the user experience offered by StumbleUpon. In my opinion it's sort of strange. It's surprising and therefore wrong. But that's just my opinion.
Is it possible to get up to date contents from an iframe? Lemme explain the problem I am encountering:
function modify_iframe(url){
my_iframe.src = url;
iframe_content = my_iframe.contentDocument;
//....code to modify the content goes here,,,,
}
The first time I call modify_iframe(url_a) it sets the source as I would expect but the iframe_content is a blank document.
The second time I run modify_iframe(url_b) it sets the source as I would expect but the iframe_content is actually that of url_a.
So it seems that contentDocument is not returning the contents of the new source, but rather the source before it was changed. Anyone know why that is and if there is a way around it?
Additional background info: We have been adding an event listener to fire off on the iframe load event which occurs when the src is changed. This was giving us the contents when calling contentDocument; however, users were being prompted that our site had unauthenticated content even though we use https for everything including the src. After removing the event listener we no longer receive the unauthenticated content warning, but the contentDocument of our iframe is always one step behind as described above.
Um, first try using a setTimeout to wait for the page content to load. But that's not a nice solution. What browser are you testing on? If it were me I would try to get to the bottom of the "unauthenticated content" error prompt.