EXTJS grid rendering - django

I'm having difficulty rendering my EXTJS grid that rides on top of a django app. The grid is only displayed some of the time. When the grid is supposed to be displayed it works. When the grid is not supposed to be displayed I get a "ct is not defined" error from extjs-core. I researched this error and it seems it occurs when my <div id="my-grid"> is not defined. The div is defined inside a grid.html that is only loaded some of the time.
These are my files.
view_main.js - I define all of my objects here inside Ext.onReady.
Ext.onReady(function(){
var grid = new Ext.grid.GridPanel({
border: false,
//...
}
grid.render('my-grid') // comment this out and "ct is not defined" goes away
// but the grid never renders in grid.html
base.html - my base django file that my templates extend. This file also loads my view_main.js file.
<!-- Load Script -->
<script type="text/javascript" src="/site_media/js/view_main.js" ></script>
grid.html - the grid html file that gets rendered inside an EXTJS TabPanel.
<div id="my-grid" style="border: height: 800px; width: 800px;"></div>
I don't want to even attempt to render my grid unless grid.html is being displayed. But the grid doesn't work unless I put grid.render inside of view_main.js
If I try to put the render script inside grid.html the I get "grid is not defined error"
<script type="text/javascript" >
Ext.onReady(function(){
grid.render('my-grid');
}
</script>
How can I only render the grid when grid.html is loaded?

If you're just trying to avoid that error, try checking for the existence of 'my-grid',
Ext.onReady(function() {
if( (Ext.get('my-grid')) !== null)
{
grid.render('my-grid');
}
});

Related

Removing loading screen and spinner after all contents of the window have loaded but before iframes have finished loading

I am using a loading screen with a spinner that is displayed before all contents in the window have loaded. It works well on all pages and the window loads very fast on webpages with less content but on one of my pages, I am loading many iframes that embed youtube videos. $(window).on('load', function(){}); doesn't trigger until all contents have loaded, including iframes. That means that loading takes a long time and the loading screen with the spinner is shown long after the browser has finished loading the HTML, CSS, JS, and all images. I want to use skeleton loading for the iframes after the HTML, CSS, JS, and all images have loaded to cut down on perceived load time. Is there a way to tell that the rest of the window has fully loaded but the iframes are still loading? This is what I am currently doing to remove the loading screen with the spinner:
<html>
<head>
</head>
<div class="spinner-wrapper">
<div class="spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
<body>
{% for video in range(videos|length) %}
<iframe class="yvideo" src="{{ "https://www.youtube.com/embed/%s" + videos[video]}.get("url") }}"></iframe>
{% endfor %}
<script type=module src="{{ url_for('static', filename='js/video.js') }}"></script>
</body>
</html>
videos.js:
$(window).on('load', function() {
preloaderFadeOutTime = 300;
function hidePreloader() {
var preloader = $('.spinner-wrapper');
preloader.fadeOut(preloaderFadeOutTime);
}
hidePreloader();
});
There can be multiple ways to solve this issue:
One simple approach can be to keep source of iframes empty initially and dynamically set source of iframes upon window.load.
Here sample code:
<script>
$(window).on('load', function() {
document.getElementById('myIframe').src = "your URL";
document.getElementById('myIframe2').src = "your URL";
preloaderFadeOutTime = 300;
function hidePreloader() {
var preloader = $('.spinner-wrapper');
preloader.fadeOut(preloaderFadeOutTime);
}
hidePreloader();
});
</script>
<iframe id="myIframe" src="" ></iframe>
<iframe id="myIframe2" src="" ></iframe>
EDIT:
If you cannot change the video.js file but can create your own js files which can interact with html on the page then do below in your custom js file:
//your external js
// first get collection of your iframes by class
var listOfIframes = document.getElementsByClassName("yvideo");
for (let item of listOfIframes) {
item.src = ""; // set them to empty.
}
window.addEventListener("load", function() {
//once page is loaded then populate the source with your json file.
for (let item of listOfIframes) {
item.src = "URLs from JSON";
}
});
Second approach:
Instead of calling hidePreloader() only at window.load. You can also check for the rest of the items in your page that if they are loaded or not. Once they are loaded, then you can use call hidePreloader()

Ember JS Implement a splash screen / loading startup screen

What is the best way to implement a loading screen in Ember 2.5? What I want to achieve is: show splash screen -> load data in background -> when DOM is ready, hide splash screen.
I tried several options, but I cannot achieve to hide the splash screen when the document is ready. I am loading a large table, so it will take some time to finish the DOM, so model-ready is not the right hook.
I did this by adding custom HTML (simple loading div) to the app/index.html:
<body>
<div class="loading-overlay" id="initialLoading"></div>
{{content-for "body"}}
<script src="assets/vendor.js"></script>
<script src="assets/event.js"></script>
{{content-for "body-footer"}}
</body>
Then I added the following to my app/application/route.js:
actions: {
loading(transition/* , originRoute*/) {
let controller = this.get('controller');
if(controller) {
controller.set('currentlyLoading', true);
}
transition.promise.finally(function() {
$("#initialLoading").remove();
if(controller) {
controller.set('currentlyLoading', false);
}
});
}
}
In my app/application/template.hbs I also had to add the loading div:
{{#if currentlyLoading}}
<div class="loading-overlay"></div>
{{/if}}
So what does happen?
index.html is loaded and no javascript is parsed yet: your loading screen is visible.
index.html is loaded and your javascript has been parsed. ember.js calls the loading action and sets currentlyLoading to true: both loading screens are shown.
the transition is complete, the first loading and second loading screen get removed
for every transition that is now happening, the loading screen is shown. To remove this behaviour, remove the second loading screen logic.
I hope it helps.

Foundation interchange image swap does not work correctly

The problem:
When I resize the window the images will only sometimes change. It's almost like they get stuck / the resize event is not being captured properly by foundation. If I start resizing the window like a rabid monkey it will occasionally swap the image. If I resize the window according to the media queries and then refresh the page the correct image renders. This appears to be a resize only issue.
Other details:
I have just a regular .html file (new site hosted from IIS on a separate machine) with a simple demo of Interchange image swapping.
If I manually call: $(document).foundation("interchange", "resize"); the image will swap correctly.
Foundation version 5.3.1
Testing in Chrome 36 and Firefox 31.
So far the only built in media query that works is (default). (medium), (large) etc. do nothing, I have to write out the actually query to get it to work (or manually create them using named_queries. This may be an unrelated problem but does seem strange to me.
<html>
<head>
<title>Interchange</title>
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>
<script type='text/javascript' src='/foundation.js'></script>
<script type='text/javascript' src='/foundation.interchange.js'></script>
<link rel='stylesheet' href='/foundation.css' />
<link rel='stylesheet' href='/normalize.css' />
<script type='text/javascript'>
$(function () {
$(document).foundation();
$(document).on('replace', function (e, newVal) {
console.log(newVal);
});
// Adding this horrible hack will make it work 100% of the time.
// BUT THIS SHOULD NOT BE NECESSARY!
//$(window).resize(function(){
// $(document).foundation("interchange", "resize");
//})
});
</script>
</head>
<body>
<img data-interchange="[/images/space-small.jpg, (default)], [/images/space-medium.jpg, (only screen and (min-width: 641px))], [/images/space-large.jpg, (only screen and (min-width: 1000px))]">
</body>
</html>
I found the answer to my own question and it was indeed that odd media queries issue I described in the OP that lead me to the problem.
Foundation's javascript is dependent on the Foundation CSS existing before it initializes.
All I had to do was make sure the CSS link was above the script include and everything started working as expected.
Not sure this will help anyone, but I was getting the same issue but ONLY on Chrome. I added the foundation.min.css to my page like b1j suggested and voila! unfortunately though as I used the SASS version I couldn't just leave this included into the page as I would have double the amount of css included into my page. So I pasted the foundation.css contents into a style tag in the head of my document and deleted its contents bit by bit until I found the piece of css that fixed it. Here it is:
meta.foundation-mq-small {
font-family: "/only screen/";
width: 0em; }
meta.foundation-mq-medium {
font-family: "/only screen and (min-width:40.063em)/";
width: 40.063em; }
meta.foundation-mq-large {
font-family: "/only screen and (min-width:64.063em)/";
width: 64.063em; }
meta.foundation-mq-xlarge {
font-family: "/only screen and (min-width:90.063em)/";
width: 90.063em; }
meta.foundation-mq-xxlarge {
font-family: "/only screen and (min-width:120.063em)/";
width: 120.063em; }
Not sure why this wasn't compiled into my CSS but I will look, but incase anyone needs a quick fix, this should do it!

Why does d3 always append to the body instead of my selection?

I am using d3js in a django web app. I have a static js script that contains a function to render a visualization given some data (passed in the context) and a selection (e.g. histogram(data,selection)). Why would d3 ignore the passed selection and directly append to the body?
This is a simplified version of my code.
Template:
{% load staticfiles %}
<script type="text/javascript" src="{% static 'd3.js' %}"></script>
<script src="{% static 'myd3vis.js' %}"></script>
<body>
<div class="vis"></div>
...
</body>
<script type="text/javascript">
mselection = d3.select(".visualization")
data = {{data|safe}}
histogram(data,selection)
</script>
In myd3vis.js file I define the histogram(data,selection) function, which contains something like this:
svg = console.append("svg").attr({"class":"visualization",
"width": 100,
"height":200})
...
When the template loads, the visualization svg is always appended to the body, instead of being appended to the <div class="vis"> element. Any idea why this would happen?
In most browsers’ JavaScript environments, console is a global object unrelated to the DOM – it provides debugging functions (e.g. console.log())… unless you’re clobbering it with a d3 DOM selection elsewhere, console.append() is unlikely to behave the way you seem to think it will.
Replace console with a bona-fide d3 selection, like:
var svg = d3.select('div.vis').attr(…); // et cetera
and inspect this object, to ensure your DOM logic is sound.

Child div to 100% when parent's height is dynamical | HTML/CSS

I want the image to be centered next to the text.The amount of text will be different in each box so I can't set the height.As I research people mainly use two ways of vertical centering.Using line-height which I can't use, because I don't have fixed height.Second one is using absolute positioning which I can't use, because left div with image inside will cover the text.If I set padding to text, when image is not there it won't look good.
The best I could think of is to use jQuery to get and set the container height, and then set the margin according to the height.
<div class="container">
<div class="image_holder">
<img src="http://blog.oxforddictionaries.com/wpcms/wp-content/uploads/cat-160x160.jpg" alt="cat" />
</div>
<p>text</p>
</div>
<style type="text/css">
.container {
width:600px;
overflow:hidden; }
.image_holder {
width:100px;
height:100%;
float:left;
background:#eaf0ff; }
p {
width:500px;
float:left; }
</style>
<script>
$('.container').css('height', $('.container').height() );
$('.image_holder').css('margin-top', ( $('.container').height() - $('.image_holder img').height() ) / 2 );
</script>
Is there a way to do it cleanly with pure CSS ?
The best solution I came up with is to absolutely position the picture inside the box and then use javascript to remove padding if there is no image in the box.