How can one page access a popup window's form data? - javascript

Scenario
I have web page, let's call it Window #1, that contains a list of people including their name and email.
There will be a button on this page that user can click to open a new window (Window #2). The user will click the button, and a new window will open and the user will add additional people.
When they are finished adding users in Window #2, they would click "Save." Instead of using a POST to send this form back to the server, I want update the original page and model (Window #1) with the information entered in Window #2.
I'm looking for explanation of how you could solve this solution using combination of the MVC framework and/or JavaScript.
Current Knowledge
I'm fairly new to ASP.NET MVC and JavaScript, so I'm not sure whether this task is possible and what it would entail. I attempted to perform a window.open for Window #2, but then Window #1 doesn't have access to Window #2 and vice versa. I considered partial views as well, but I wasn't sure how that structuring would work.
I've attempted to research this situation, but I'm not entirely sure that my terminology is correct and thus I wasn't able to find much information regarding the topic.
Any help would be greatly appreciated!

You could do the initial load of Window#1 using a traditional MVC Get method. You could also use bootstrap modal for Window#2. You would then use JQuery's post method to send the new users to a Post method in your MVC controller. This method would ideally return something like a JSON objec with an updated list of users. You would then rebuild the list in your DOM when JQuery's Post method returns.
Alternatively, you could look into something like Knockout.js instead of using JQuery's Post method and manually rebuilding the user list. Knockout lends itself very well to scenarios like this.

The child window can reference the parent window. The child window can then reference the DOM of the parent by using window.opener. An example from w3schools:
// Open a new window
var myWindow = window.open("", "myWindow", "width=200, height=100");
// Write some text in the new window
myWindow.document.write("<p>This is 'myWindow'</p>");
// Write some text in the window that created the new window
myWindow.opener.document.write("<p>This is the source window!</p>");
Selectors can be used to modify the parent's DOM in the manner requested from the initial question.

Related

How to pass values from HTML webresource to javascript on window close MSCRM

I am opening HTML webresource using Xrm.Navigation.openWebResource but on closing of HTML window I want to pass values from HTML to javascript file from where it is opened. Is there call back function can be implemented?
If I open HTML window using window.open I can call parent javascript function using window.opener.functionname on close but click but I want to know how I can pass values to parent javascript file on close button click of HTML window.
I tried with window.parent.opener.Functionname() but it is not working - getting functionname is undefined but it is defined in parent javascript. Pls suggest.
If you're using the 'old' (as it not the unified interface) user interface with turboforms enabled then the parents javascript is actually in a extra iframe called customScriptFrame, and not on the parent itself.
To call something on the parent you can use
parent.customScriptsFrame.functionname() for IE
and
parent.customScriptsFrame.contentWindow.functionname() on chrome.
On the unified interface its much the same, but far more troublesome.
Now the scripts are in a iframe called ClientApiFrame_[n] where [n] is some random number. And i haven't found a good way to determin that number ahead of time from a webresource.
You could go over all frames of the parent in javascript (parent.frames) to find one that has a id that starts with ClientApiFrame_ but that will throw errors trying to read frames with sources set to external domains, and i dont think is very good practice.
Another possibility is registering the function you want to call with the parent ahead of time. so in the main javascript use this.
parent.functionname = functionname
And then from the webResource you can use the normal
parent.functionname
If the webresource is embedded in the form, then use window.parent
If you Xrm.Navigation.openWebResource to open it, then use window.opener

Trying to access parent window element from child [duplicate]

I'm playing around with a few ideas for a project, and one of them needs to somehow have communication between 2 different browser pages/windows/tabs. My goal is this:
I have a main page that has a link that opens a new tab/window. In that window, there is the choice to 'navigate' a part of the main page. The issue is, to my knowledge, there are no physical ties between open windows (and no handle on the 'parent' window accessible by the child).
I've been trying to use opener to reference the parent window, but functions and elements are not responding to my calls from the child.
Is there any way for a child/other window to access elements/functions on a parent window?
I'm attempting to avoid using simulated tabs/frames (which would be easy enough to just reference the parent, or window element to accomplish the goal).
Yes, actually that is possible. If you use window.open() in JavaScript, you can use window.opener. and submit whatever requests you would normally make. Like:
window.opener.document.getElementById('id').innerHTML = "hello";
or using jQuery,
$(window.opener.document).find('#tableInParent').html("hello");
Read more here: http://wisercoder.com/javascript-jquery-parent-windows/
JSFIDDLE HERE
I hope this helps!

FullCalendar print on iPad

I have been working on this task off and on for awhile trying to find an optimal solution (other than telling users to disable popup blocking) and am stumped.
Essentially how it works is this (I omit code because there is a lot of it and propriety info):
I have an angular app implemented in an angular and utilizes fullcalendar.js who's content I want to print. Inside my angular controller I have the jQuery that manages the calendar itself (don't hit my fingers with a ruler please :) )
I want a specific set of styles when I want to print the calendar, so I have a directive that prepares all the content to be ported, and then use a uniform angular factory that is used for all printing activities. This uniform factory opens a new window that contains all the new styles I want and, via a callback, "cleans up" the HTML, which in my case I use for porting the HTML content of the calendar over to the new window.
So the flow basically is this: User clicks print button -> click event in calendar print directive is invoked, the directive calls the factory. -> Factory opens a new window and ports the content via the callback from the directive and then calls JavaScript's print() to print the window.
The problem I am encountering is this:
The print works fine on PC and Mac, but on iOS safari, the window does not pop up. I found that the issue was because iOS Safari requires all new window popups to be inside a click event.
To get around this, I thought I would add some modification to the uniform factory to suit my case: I would open a new window in the directive's click event, then pass a reference of that window into the factory, which can then use the reference to add the html content to its body. This introduced another issue with iOS Safari in that it stalls javascript execution of parent windows if a child window is open, so once the new window is open, the generation of the HTML and the calling of the factory is stalled until the user switches back to the parent tab. This is the point where I got stumped. Any suggested way to get around these issues? Or would I be stuck telling the user to disable popup blocking?
once the new window is open, the generation of the HTML and the
calling of the factory is stalled...
Can you change so the generation of HTML and factory call is made before opening the new window? Otherwise it sounds like you need to avoid the popup.
If you want to display another view in the same window, use ngInclude.
You can choose to switch the path of the ngInclude to swap the HTML or combine with ngShow to show and hide the correct parts when the user clicks.
It sounds like you use a factory as a parent scope and if so it should be converted to a controller that acts as a global scope above the different views.
If this is on the right track I could make a plunkr out of it.
Also, check out fullcalendar-ui for a premade directive if you want to go towards best practice.
Good luck!
After ~3 times coming and going from this over the course of a month, I finally figured it out.
Inside my directive that prepares the content to be printed, I generate a new calendar, then call the rest of the code (including the factory that opens a new window) inside a document.ready. Having the code inside the ready check seems to cause iOS Safari to think it is no longer directly inside a click event, so it would sometimes block the new window popup. Removing the document.ready check seems to have made it work, and has no ill effect on the other browsers.
I decided to create a function inside the directive for the factory call and call inside a document.ready if not iOS, otherwise just call it, to preserve functionality for desktop browsers.

html form not holding it's elements' attributes when being passed from web page to child iframe?

I have a form that gets completed on a webpage by the user,
when the user submits the form, I bring up a bootstrap modal dialog, this dialog has an iframe in it that loads the form from the parent window calling a function in it like so:
//parent window
var formToSubmit;
function getForm(){
return formToSubmit;
}
$("#submitButton").click(function(){
//alterations to the elements in $("mainForm")
formToSubmit = $("mainForm");
$("#modalDialog").modal();
//...
});
//modal iframe
var parentForm = parent.window.getForm();
$("#mainDiv").append(parentForm[0].outerHTML);
$("form").submit(function(){
parent.window.closeModalWindow(); //not sure whether this will close AFTER the form is completely submitted yet
});
$("form").submit();
My problem is that I'm submitting these forms to microsoft sql server reporting services and it takes every input element as a parameter. I have no control over this.
So when the user clicks submit in the main form, I disable all the elements that must not be set as parameters, the thing is; as soon as I get the form from the parent window and append it to the modal iframe, it seems as all of those changes are lost, is there any way to preserve this?
Your problem likely has to do with the call to outerHTML on the form. First of all, implementations of outerHTML have been different across browsers, so I would avoid using it if possible. Second, outerHTML does not necessarily contain the live DOM element, but merely a dump of it as a string.
Therefore, I suggest deep cloning the form before passing it to your IFRAME.
With jQuery (see docs):
$("#mainDiv").append(parentForm.clone(true));
Or plain JavaScript (see docs):
document.getElementByid('mainDiv').appendChild(parentForm[0].cloneNode(true));
I ran some tests to verify this, and as long as you're cloning the form, you will get the results you're expecting.
As a side note, why are you duplicating the form in a modal? Are you re-creating it as a "please review" type thing for the user? It seems like a strange process. I only ask, because perhaps there are better ways to do what you're asking. Anyway, the answer I've given should help.

Filepicker.io widget appending to "window.history"

The Filepicker.io modal widget (specifically the "IMAGE_SEARCH" service) appends to the window.history in the DOM after a search is made. This creates an issue working with Backbone.js when attempting to go back a previous page.
What causes this, and is there any way to prevent it?
[edit] Incorrectly referenced "IMAGE_SEARCH"
What causes this:
Navigation around the modal manipulates window.location.hash for compatibility with the window view and a number of other conveniences. Why these changes are affecting the window.history outside the iframe sandbox, I'm not sure.
How to prevent it:
I'm looking into whether we are leaking state somehow, but one easy way to prevent it is to use the {container: 'window'} option for filepicker.pick(), so that the dialog is created in a separate window.

Categories