How to use Meteor FlowRouter.withReplaceState - meteor

This is a different problem from a similar question about 'reload'. This use case has to use 'withReplaceState' to handle back button reloading.
I've found the FlowRouter documentation for FlowRouter.withReplaceState(fn), but I've been unable to find specific code examples and can't get it working.
My problem is with Isotope, a plugin that moves elements around when window is resized. User sometimes visits Isotope page, goes to another page, re-sizes window, then presses "back" button to return to Isotope page. Page has to reload to re-trigger the Isotope layout correctly for the new window size.
This is my route. How would I use FlowRouter.withReplaceState() to ensure that user who clicks back button is not seeing the cached page?
FlowRouter.route( '/work', {
action: function() {
BlazeLayout.render( 'body-static', {
content: 'work',
});
},
});

Related

ASP.Net popup for Chrome

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.

FlowRouter without page reload

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.

Router links with iron-router going to "random" places on the page

I am using iron-router with a meteor application. A strange thing is happening. Certain links for routes (for instance /purchase) is taking me to the middle or the bottom of the page. The behavior seems to be random. Is there any way to ensure these take you to the top of the page?
Tell the window to scroll top when navigated to a route:
route: {
name: 'name'
template: 'template'
onAfterAction: function () {
scrollTop();
}
}
function scrollTop() {
window.scrollTo(0, 0);
}
Try using okgrow:router-autoscroll package.
meteor add okgrow:router-autoscroll
Scroll to top is okay for a forward journey in your site but If a user wants to go back it will put them back at the top of the previous page. The autoscroll package maintains the page position so when you click back it scrolls to where you were. It also has support for hash tag anchors

Backbone menu refresh handling

I am using yeoman workflow http://yeoman.io/ ,
I have build a simple menu layout to handle the menu css :
var menu = new Backbone.Layout({
template: "layouts/menu",
className: "menu",
events: {
'click a': 'changeActive'
},
changeActive: function(e) {
$(e.target).parent().siblings('.active').removeClass('active');
$(e.target).parent().addClass('active');
...
It work fine but I am facing a problem in which I bump into very often,
when user clicks on browser's refresh button of course it doesn't remember the state and display
the initial state.
What is the best way to solve that ?
You could save the last selected value to the cookie or to the localStorage and inside the initialize method make it active.
You can update the hash and save selected value there. On initialize just get it and make proper menu active.

jQuery: fadeout an image when clicking an ASP.NET ImageButton

I'm building a photo gallery in ASP.NET. The user can browse thumbnails along the left and select one, which brings a preview-sized version into the right pane of the page.
I'd like to fade between the images, so that the current one fades out and the next one fades in. I'm using jQuery to fade the preview image in after it is loaded, which works great. Unfortunately, I can't get the fadeOut script to run before the click event posts the page back to the server. The thumbnails are ASP.NET ImageButtons, which means they're <input> tags.
Is there a way to get the postback to delay just long enough for the image to fade out? I've seen some tricks with the form onSubmit and setTimeout() but that would affect all the links and buttons on the page. I want to delay postback for the thumbnails only.
TIA
EDIT: Based on my research, and trying the suggestions below, it may be possible to delay the postback to accomplish this but it's not the best approach on several levels. To get a clean fade transition between images, in the future I would not do any posting back at all. I would use jQuery exclusively for the fadeout, load, fadein.
Try adding a return false to your function that handles the fadein/out... It should prevent the page postback from occurring...
$('#<%= this.aspbutton.ClientId%>').click(function(){
$('#myDiv').fadeout("slow");
return false;
});
I'm not sure what you are getting on the PostBack where you would want to fade out an image and then fade one in. Have you considered using AJAX for that? You could even have the thumbnail image contain the necessary information within the image tags for the larger image.
Take a look at the jQuery Lightbox plugin. I have implemented this plugin and modified the .JS a bit to allow for viewing a higher resolution photo in addition to the web view. Check it out here.
$('#<%= this.aspbutton.ClientId%>').click(function(){
var $btn = $(this);
$('#myDiv').fadeout("slow", function() {
$btn.unbind('click').click();
});
return false;
});
Here's the solution I used:
Since I AM using MS AJAX with an UpdatePanel, I can use the client-side AJAX event handler.
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(fadeOut);
function fadeOut() {
if ($('.mainImage').length > 0) {
$('.mainImage').fadeOut('normal');
}
}
This gives me the exact behavior I wanted- any time the user navigates between thumbnails, the image fades out, loads, then the new one fades in.
HOWEVER...
This is still not ideal, as there is a pause between fades while the page posts back. It will work for now but in the long run it would be better to use jQuery to set the preview image rather than the thumbnails posting back as ImageButtons.

Resources