I just started playing around with Meteor and Iron Router to create a simple site. There are a few links on the nav bar of the site and one of them is called random. The idea is that when a user clicks it, a random post would display at the page.
Now Iron Router seems to prevent a page from reloading if it's the same link with the current one. That's a great feature except in my case I need it to reload so the user can see a new post.
Here's the relevant code:
Router.route('/random', function() {
console.log("running this!");
this.layout('SinglePostLayout', {
data: function () { return draw(Posts, {}) }
});
this.render('post');
The draw function returns a post in the collection. It's fun from perfect but that's not relevant here. I confirmed the code only ran once by using console.log.
Is there a way around this? I want to preserve the no reloading behaviour for all other links except for the random one. I've searched for answers for a while but couldn't find anything.
Thanks!
Since you are not using dynamic routes to show each post.
You can use the Location.reload() method from the window object, and use pure Javascript.
if(Meteor.isClient){
Template.home.events({
'click #randomHref':function(){
document.location.reload(true);
// Router.go('/') don't work.
}
})
}
Related
My Electron App has an Menu in the every .html Page witch is controlled by an controller.js
$(document).ready(function() {
const app = require("electron").remote.app;
const { remote } = require("electron");
$("#btn1").click(function() {
window.location = "index.html";
});
$("#btn2").click(function() {
window.location = "aaa.html";
});
$("#btn3").click(function() {
window.location = "bbb.html";
});
$("#btn4").click(function() {
window.location = "ccc.html";
});
$("#btn5").click(function() {
window.location = "ddd.html";
});
$("#btn6").click(function() {
window.location = "eee.html";
});
$("#btn7").click(function() {
window.location = "fff.html";
});
});
In the every Html Page i have in the head section so the controller.js can work! My question now is how to make this without to reload all the time the window when switching the page?
For example When I go to aaa.html It feels like in the Browser a have for a few Milliseconds a White screen then it goes to the new Page, How I can make this work without White Window when Clicking a Button to go to a new Page? I want the Content to be loaded when I click the Button without this Browser feeling.
Any Ideas how I can do this or what I can do better here? Thank you
To answer the question technically : you could get the content of your pages using the fetch API, and then parse them using a DOMParser and then replace the current content of your page (or just a part of it, say not the header and footer, but everything else) with what you just parsed, using the history API
Making this all work nicely together is not straightforward though, and you will never get rid of some level of rendering 'flashes' in some places in most cases.
What you probably want to build is a single page application, I suggest you check out React, Vue or Angular and build from those
Edit :
An other solution is to load everything upfront and then inject/remove elements using javascript, for this solution, I would recommend using templates (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
Besides solving the page request problem, i would advise to adopt available frameworks and libraries that support in building single page applications. A lot of work has already been done for you.
Personally i would use React with the react-router package to create an SPA. If you want to reduce flashes between transitions, you need to avoid re-rendering the whole page. This is exactly what UI libraries like React do.
We want to have a back button in our site
but history.back in javascript does not help us.
We need this function only run on the site and if the user comes from other site, clicking the return button on the previous site should not return.
In fact, we want a return button to run on our site only.
my code is
<i class="fas fa-arrow-left"></i><span class="btn-text">Back</span>
This only works for your own made back button and won't work with the browser back button
There is two ways to achieve that: a simple but not always reliable method and a complex one but always good.
1- The simple method
You use document.referrer and ensure the domain is yours before calling history.back().
2- The complex method
You could register a JavaScript function on page load to get the first URL the internaut land which you could store using history.pushState. Before calling the back function, you could ensure this is not that page. Though, this idea is not complete as the user could probably have landed on this page twice. i.e. Home->Product->Home. I'll let you search for further code that would let you counter this problem.
This code checks the history of back button of the browser on its click event:
$('#backbtn').click(function () {
if (document.referrer.includes(window.location.hostname)) {
window.history.back();
} else {
window.location.href = "/your/path";
}
});
Title is probably a little messy. Basically what I'm trying to do is to create a custom function that will modify an object properties, then return that object, and then call a function.
A little background on what I'm doing : Trying my best with the Zendesk API to use a web widget on my webpage. Basically this web widget is configured to be a HelpCenter on startup, which then shows a button for either live chat or email, depending on the state. The main property in question here is called 'suppress' which disables one of the widget pages (chat, email & helpCenter). And my goal is to make that custom function 'suppress' 2 of the 3 widget pages so it only shows one. Then a API func called zE.activate() would open up the widget.
I know this is a lot of text, let me show you the code I've got so far :
<script>
function setChatPopOutProps(window) {
window.zESettings = {
webWidget: {
contactForm: {
suppress: true
},
helpCenter: {
suppress: true
}
}
};
return window.zESettings;
};
function chatPopOut() {
setChatPopOutProps(window);
zE.activate();
};
</script>
Now when I click on the button that has chatPopOut() assigned, the zE.activate() works since it opens up the widget, but basically the setChatPopOutProps(window) didn't seem to work.
I also tried the following :
Not returning window or window.zESettings
Putting everything under a single function by putting zE.activate() at the end of zESettings or just after the return window or window.zESettings
If you need to see the widget in action to have an idea, you can see it right here. Click on the green button on the bottom right, type anything, and you'll see the contact form button pop up. This button changes for a chat button when a live chat agent is available.
Now I know this is something that I should normally work out with Zendesk directly, which I tried, but they told me that there's nothing that can do what I'm trying to accomplish, but I really feel like this has something to do with the way I'm doing things in javascript and not the way the API is built..
Does anyone have an idea ? I would really appreciate it.
P.S. This is my 2nd post, so I apologize in advance for mistakes I probably made in this question.
Sadly, it turns out that what you are trying to accomplish just isn't possible. As the zE.settings get applied when the widget is first initialized, so there is no way to dynamically alter the widget settings without doing an action such as refreshing the page and re-initializing the widget. As far I can see from your code, I dont think you want to refresh the page everytime, and reinitialize the widget just to apply those settings that you listed above.
I have the 2 sets of code:
Saves the data
myapp.activeDataWorkspace.ProjectHandlerData.saveChanges();
2.Refreshes the page
window.location.reload();
is there a way to make both of these work together on one button, as currently when i click save, the browser recognizes the changes and the (are you sure you want to leave the page) message or something along those lines pops up..
cheers
This is for the HTML client, right?
Assuming that is the case:
saveChanges() is an asynchronous operation, so you'd want to do:
myapp.activeDataWorkspace.ProjectHandlerData.saveChanges().then(function () {
window.location.reload();
});
That way it will wait until it is finished saving the changes before it reloads the screen.
However, there is a smoother way to do it, at least from the user perspective it's smoother.
On the edit screen, leave the Save method out, let LightSwitch handle that. When the user clicks save, it will close the edit screen, and go back to where they were before. Using the options parameter of the showScreen method, we can change that behavior.
Change the method that calls the edit screen like this:
myapp.showEditProject(screen.Project, {
afterClosed: function (editScreen) {
myapp.showViewProject(editScreen.Project);
}
});
This way, after the edit screen is closed, and it has handled the save changes operation for you, the application will automatically navigate to the details view screen of the recently edited item.
If you are instead wanting to refresh the browse screen after adding a new entity:
myapp.showAddEditProject(null, {
beforeShown: function (addEditScreen) {
addEditScreen.Project = new myapp.Project();
},
afterClosed: function () {
screen.Projects.load();
}
});
Those two options, beforeShown and afterClosed, give you a lot of really cool abilities to influence the navigation in your application.
I have learnt that you can save from a add/edit window, and reload the main page you are going back to by doing the following:
For Example: (adding an order to an order screen)
click on your button to add the order
enter the details required.
hit your custom save button with your validation included.
before your commitChanges(); write in the following line: screen.OrderLine.OrderTable.details.refresh(); "This needs applying to your scenario"
when you return to your screen your details should have been updated (for example the total value now displays the correct value in my case)
hope this helps...
I'm using the hot towel template, and I'm trying to understand how to navigate to a different view via a javascript call. When my page loads, it looks like this:
Then, if I click any other button, then click the apps button again, I wrote some test code to just take the user to the ping page. This is in the apps view model:
function activate() {
if (initialized) { router.navigateTo("#/ping"); return; }
// more code here (doesn't get hit the second time through)
}
But what happens is the URL is correctly the ping URL, and the ping button is selected, but the actual content is still showing the applications:
If I want to navigate to another page without clicking in the navbar at the top, how should that be done?
Your 'router.navigateTo('#/ping') is correct.
But when activate method is called, lots of heavy tasks are being done by durandal, it's too late for
your commanding, if you want to prevent opening a page and instead of that You'd like to go to
another page , then you can use 'CanActivate' method as following :
function canActivate() {
if (initialized) { router.navigateTo("#/ping"); return false;
/* return false to prevent opening a page */ }
else return true;
}
Also your application's performance will be boosted too
Good luck.