I'm building a React app, using Foundation 6 for my UI. So far this has worked pretty well, but I'm now getting to where I'm changing the markup based on user events instead of just on page load, and the Foundation Plugins aren't working for newly rendered markup.
As a simple example, I've got a Login menu that renders as a Foundation Dropdown. Clicking on an entry in this will, once the user has logged in, cause this to be removed and a different menu to replace it - with the User Profile and the Logout links on it.
My initial attempt simply had $(document).foundation() called in the componentDidMount method of the top level UI. This worked great for everything rendered in the initial page load, but doesn't pick up anything rendered later on.
I've just tried replacing this with a MutationObserver, and again this works perfectly for anything rendered in the initial page load, but when the menu changes I instead get: "Tried to initialize dropdown-menu on an element that already has a Foundation plugin" - despite this being rendered inside a different React Component.
Is there a correct way to get this to work?
Related
So, after a new browsers update on last year, a menu component doesn't work properly anymore.
When the page loads, the menus appears like this
But in the html they are there:
The most stranger part is when a zoom-in or zoom-out the page, they show up.
I don't know whats is going on. I had read the last changelogs, but I couldn't find anything that leads me on somenthig.
On the project we use AngularJS version 1.6.4 and AngularJS Material with SCSS for components.
I have an existing website composed of individual pages (each page is a different tool that requires some user input (ie forms), and each with it's own set of javascript functions to populate dropdown lists, etc on that page). Each of the tools is accessed from the main index.html.
Instead of each tool being its own "stand-alone" page that is invoked from index.html, I'd like each tool to be displayed in an iFrame instead on the main page. This way the main page remains static, while only updating the iframe with whatever tool the user selects. So say on the main index page, I have a 3 tools menu (collect logs, collect KPIs, collect status), along with an iFrame. If the user selects collect logs for example, the menu containing "collect logs" stays there, but the "collect logs" page is displayed in the iFrame.
My problem is that all the HTML content works fine, but none of the javascript code in the selected tool page works (ie none of the drop downs get populated since it's the javascript code in the page that does that by reading a file on the server).
Is there an easy way to port each tool page (html+javascript) to an iFrame without having to re-write tons of code (in my naivety I thought simply invoking the page inside an iFrame using target='' in the href would work)? Or is there a better method of accomplishing what I'm trying to do? Maybe iFrame isn't the solution.
Content in iframes remain autonomous from the wrapper app, so it makes sense that it's not working correctly. Other than building a listener for a click event associated with the div wrapped around the iframe, the iframe document isn't accessible if it points to a different origin. (See [same-origin policy]
(https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy))
To stay with simple html/css/js solution:
You can use a regular div to wrap each 'stand-alone' content and then just use whatever button/navigation target you have display that div and hide the previous by changing their css display style with the onClick event.
More invasive option:
You may want to consider using a more modular JS approach, like React JS, to build components vs pages and utilize React's structure to toggle components.
With react you can render each 'tool' when the user selects it . You would be able to utilize React component state as well to help in storing data and such for the life-cycle of the component.
I'm currently working on an old project, which has its "own way" of doing a single page application (does Ajax calls to an MVC application, gets the view, replaces the view client-side, appends styles and lots of other stuff!!), and although not ideal, currently I'm stuck with it!
I am trying to integrate an existing React application into this site, and what I'm doing is to use create-react-app and then build to create the bundles, and in the application, in the view begin returned from the server for a specific page, I'm putting script and link tags, pointing to my bundle files. It's worth noting that this server view is a partial ASP.NET MVC view, so my script and link tags are somehow part of the body.
I'm also using styled-components in my React application.
Now, here's the problem: when I first load the page I mentioned, my script is loaded, and I can see all my components being styled properly, but when I navigate in the existing custom SPA application, at some point, styles related to styled-components are messed up, and the only way to get them back is to reload the page.
I was inspecting the page, and I saw that styled-components is doing things with a custom link created in the head, and I see data-styled-components attribute being populated with custom class names as my components are loaded, but when the problem arises, in Chrome Developer Tools, I see that the link tag flashes as if it's changed, but it stays the same.
I have attached a GIF of the tag:
- It starts with the initial page load
- I navigate away and come back and I see more classes being appended
- I repeat the step, and I only see that it flashes
I know the post is already long, but any help is deeply appreciated. Is it possible that, with the current infrastructure, it has something to do with the fact that whenever I come back to the page, a script tag is sent from the server pointing to my React bundle?
Thanks to Max Stoiber for answering in this GitHub issue:
The reason for this behavior is exactly what I mentioned at the end of the question: every time the page is loaded, a script tag is sent from the server, containing the bundle, which in turn causes a new instance of styled-components to be created; this is not supported in styled-components, and that was the issue
I'm a self-learner and this is just one of the things I cannot wrap my head around. I use nodejs for all my web applications and wondering if react can solve the problem I am facing.
The problem: what todo when you need to show a pop-up image gallery that showcases multiple images. But we don't need to look this gallery every time the page loads, only when using clicks the open galley button.
A similar example would be what Airbnb have achieved on their listing pages:
https://www.airbnb.co.uk/rooms/432044
Now the page doesn't load all the gallery pictures when page first renders.
But when you click on the view photos, it opens the gallery, but then loads the pictures and I've noticed it has a div containing data-reactroot.
Are they using some sort of react magic? Or is it angular?
I'd really love to be able to build my components for easy reuse, but more importantly, I'd just like to understand what's going on so that the gallery content is only loaded when the photos are opened.
If someone can summarise in a paragraph, what is going on, I'm sure I can go away and learn to replicate it. I'm just not sure what I'm trying to replicate at the moment.
You can use React for that, you just need a conditional render. Basically you have a toggle in the component's state (a simple bool). And in your render for the parent component you can have something like:
render() {
<div>
...
{ this.state.showPhotos ? <PhotoPopup /> : null }
...
</div>
}
If the toggle is false, that component won't get rendered so it doesn't load. When they click the button and change the state, the toggle is true so that component WILL get rendered and the photo popup will be displayed (loading photos in the process).
That's one way to do it in React anyway. Don't forget to handle loading of photos (i.e. have some visual indication that photos are loading)
The basic approach is that you write a small React or Angular app. The responsibility of this app is probably just to render a "show photos" button, and then when it's clicked dynamically add the photo gallery HTML to the page, which is turn triggers the browser to download the images. The app and all its logic is bundled up in a single JavaScript file.
Have a read of the React docs,
https://facebook.github.io/react/docs/hello-world.html
Then start with create-react-app. It's Facebook's recommended way to build simple to medium complexity apps - it's all you'll need to achieve the above.
https://github.com/facebookincubator/create-react-app
I'm working on an angular 2 application, to keep the explication short, I have a navbar on the left, and on the rest of the page, and I will display my content.
Those content will be blocks, as in the attached image, the navbar contains 4 actions (Form, test1, details ...)
The content in the middle will display everything, but when I click on form, form will be shown in the middle, when i click on Details, the details block will be shown in the middle.
The user can scroll down and up to see the blocks.
I saw that in Angular 2 we can user Fragment to precise anchor and what blocks we want to show, but the problem is that there is a bug on the fragment functionality.
At the moment, I have a router-outlet that changes the view depending on the url in the routerLink on each button of the navbar. Should I keep using it if i want to display all the blocks/components on the same page?
Thanks for your help,
here is the screenshot
So in essence, you want a multitude of components, with a menu that doesn't really navigate, but more so has toggle buttons that either display or hide content? What should a page refresh do? Does it matter if you see the same components then? If so, you either have to store state in local storage / session storage / using ngrx... or you have to add the displayed items to the route and resolve those.
Anyhow, in the end you want one component which decides what is displayed, and all the blocks in their own components with their own selectors which you show / hide using *ngIf.
Your html would basically look like this:
<my-menu></my-menu>
<my-form *ngIf="showMenu"></my-form>
<my-test1 *ngIf="showTest1"></my-test1>