I want to open a file on a new tab but my inertia props are lost,
my approach on opening new tab is this
window.location.href = "/view/"+props.document.type+"/"+props.document.id, "_blank"
but the my inertia props are lost. It only returns a blank html page
Update: there was a missing return in OP's code.
If you open a new tab, you will have your SPA nuked. The idea is to persist it with something like cookies or alike. Give a try to that answer for a possible solution: https://stackoverflow.com/a/66872372/8816585
VueJS by default has no way to persist any state out of the box (it's client side code).
Related
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.
I have a web application written in AngularJS (version 1.0.8).
I'm using UI-Router (0.4.) to handle the state of that app.
I try to access the URL of the app from another Flex app (4.0).
In the Angular app, I have the URL:
http://localhost:8080/myApp/somePage?param01=aaa¶m02=bbb
In Angular's module.config() of that app, I do something of this sort:
$stateProvider.state("somePage", {
url: "/somePage?param01¶m02"
templateUrl: "view/somePage.html"
controller: "SomePageController"
});
Now in the Flex application, I have the following code:
var variables:URLVariables = new URLVariables();
variables.param01 = "aaa";
variables.param02 = "bbb";
var url = new URLRequest();
url.data = variables;
navigateToURL(url, "_self");
The problem is that when I press the button in the Flex app that navigates to the Angular app, I get this URL:
http://localhost:8080/myApp/somePage?param02=bbb¶m01=aaa
In the URL's query parameters, param02 comes before param01.
Then, in Angular's ui-router, I guess, it is changed to the regular URL:
http://localhost:8080/myApp/somePage?param01=aaa¶m02=bbb
My problem with this is with the browser navigation - when the user will click 'back', the browser won't navigate back to the URL of the Flex app, because there's another URL in history, where the query parameters were switched. The user will have to click 'back' twice...
Moreover, though this is an elaboration that's not necessary for the problem, so you can skip it if you'd like, the user can access that Angular app from more than 1 place (i.e. not only from the Flex app). When the user click 'Save' or 'Cancel' in the Angular app, it should be redirected to the originating page. I planned on doing it using the history.back() feature, but it's problematic due to the aforementioned phenomenon, of the URL with the query parameters switched.
Many thanks in advance,
Daniel
I solved my own problem, currently by changing the way I work with navigateToURL in Flex.
I now have something of this sort:
var queryParams:String = "param01=aaa¶m02=bbb";
url.url += "?" + queryParams;
navigateToURL(url, "_self");
This way, when I use a string built by me, instead of the URLVariables class, I can control the order of the URL query params.
Unfortunately, I still don't know why the URL query params are ordered differently every time I use the function, when I do use the URLVariables class...
i got a simple scenario where i have an administrative list of DB-Entries. On click i call the remote-attribute and display the data.
Now the Modal Dialog contains Action-Buttons like "Delete", "Approve", "Nothing".
So whenever i click one of those buttons, i'd like to get the ID of the DB-Entry.
Going by this PullRequest on GitHub on Bootstrap 2.3 there was a relatedTarget attribute on the event. Apparently on v3 this has been removed. So i'm really wondering on how i should implement this kind of feature.
//Syntax Bootstrap v2.3
$('#modal').on('show.bs.modal', function(e){
console.log(e.relatedTarget);
});
//Syntax Bootstrap v3.0
????
A fiddle shouldn't really help to understand the question, but here's one anyways
Since i have identified buttons on the modal dialog, a functionality like this works. Though for some reason i feel for this to be a little messy and I'm still wondering if there's a different solution to this:
// Button to open the Modal Dialog
Foo
// Button inside the Modal view
delete
And then the JS to get the article ID on Delete-Button-Click:
$('#delete-article').on('click', function(){
var articleId = $('#modalDiv').data('bs.modal').options.articleId;
// artticleId = 1
});
Since i have to make another "query" onto the DOM, i feel for this method to be quite dirty. If there's any other way to get the data in a more performant way, I'd gladly take that information :)
I have a number of anchors in a page. I want that when the user clicks on an anchor it would open a blank window. I have used target='_blank' and that works correctly. However, I want that if the user clicks on another link in the original page, I would like that it uses the same popup that was opened for the first window. What I do not want is that the user ends up with like 10 popups as this would be a bit messy for the user.
Is this achievable please?
Any assistance would be greately appreciated.
target is deprecated since HTML 4.01, you can however use JS like this:
test
<script>
var clicky = document.getElementById("clicky");
clicky.onclick = function(){
window.open(clicky.href, "test");
return false;
}
</script>
in the window.open, the first attribute is the URL the link should go to, the second is the name of the window, clicking any link setup like this will open in the same window.
there's better and easier ways to do this to multiple elements with jquery etc. but it all hinges on the window.open.
Instead of using _blank (which is a special value for a new window), use a name - any name would do.
target="mySpecialPopup"
When naming a window this way, every time you call it by name it uses the same instance.
Just name your target.
target='mywindow'
This should open a blank window the first click and repopulate it when other target='mywindow' links are clicked.