Bootstrap popover works on second load - javascript

I have made a webpage on Sharepoint with bootstrap and the content is populated with javascript. I am using popover in a table. The table is generated via javascript. The strange thing is that the popover works only after I made a refresh of the page/reloaded it with F5.
A popover outside of the table works fine and by first load. As well as the code runs fine without problems on my local machine, but on sharepoint it breaks down.
Here some code - initialization:
<script src="jquery-3.5.1.slim.min.js"></script>
<script src="popper.min.js"></script>
<script src="bootstrap.min.js"></script>
then the function for generating the table is called:
<body onload="javascript: GenerateTable();">
followed by the popper call:
$(function () {
$('.example-popover').popover({
})
})
The result is a table which contains the following line with the popper:
<td>Here is a question which needs a popper as info!
<div class="row justify-content-end">
Info
</div>
</td>
It seems to me like it an issue with the loading order - but can't figure out why it works locally but not on Sharepoint.

I import js from CDN, it works well in my environment.
Test code for your reference:
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<body >
<td>Here is a question which needs a popper as info!
<div class="row justify-content-end">
Info
</div>
</td>
</body>
<script>
$(function () {
$('.badge').popover();
})
</script>
Test result:
If you need further assistance,please share the full code.

The problem was the order of the javascript execution. As the code is loaded from an external javascript file the order how the code is loaded is not known.
Thus it is recommended to put the javascript function from the html file into an explicit function into the javascript file. Then the function has to be called explicitly.
Javascript File:
function PopperCall(){
$('.example-popover').popover({});
$('.popover-dismiss').popover({trigger: 'focus'});
$('[data-toggle="popover"]').popover();
}
In the HTML the loading is done by:
<body onload="javascript: GenerateTable(); PopperCall();">

Related

Includes taking a long time to load and you can see them loading

I’m including one HTML file in another, as a way to reuse my header and navigation generation logic.
The trouble is that when I browse to pages on my site, I can see the HTML that isn’t included in the include files load first. Only then you can see the menus and banners load afterwards. I’d like everything to appear to load at the same time.
Here's the rendered HTML.
And here’s a code snippet showing you how I generate these pages:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
<script>
$(function(){
$("#includeHeader").load("includes/templates/header.html");
$("#includeNavigation").load("includes/templates/navigation.html");
});
</script>
<div id="includeHeader"></div>
</head>
<body>
<div id="wrapper">
<!-- Navigation -->
<div id="includeNavigation"></div>
I’m currently working with the code to try to move any external libraries / CSS to the bottom of the page vs. in the header. But so far, that hasn’t really changed or improved anything.
You should use one of the templating languages.
If your includes are simple HTML files then you could use Handlebars or Dust - you could just copy your code and that's it, then in Javascript you would need just render these templates - see the documentation.
You could use Jade/Pug instead, but its syntax is different from the HTML, so that's not just question of copy-paste.
You are using $(handler) to load them, which is a form for $.ready(). So it waits for the document to load everything before loading your header.html and navigation.html.
Try
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
</head>
<body>
<div id="includeHeader"></div>
<script>
$("#includeHeader").load("includes/templates/header.html");
$("#includeNavigation").load("includes/templates/navigation.html");
</script>
</body>
Your problem is that the load function does not run until the document.ready event has fired. Which is probably after your page has started rendering. To get everything to appear at the same time you could use the callback from .load to show everything. So everything is hidden,
$( "#result" ).load( "ajax/test.html", function() {
/// show your stuff
});
You will of course need to know both has loaded.
I would recommend not using javascript to render HTML from a static path and would use a server side lang instead for speed.
I think it make some level fast its not waiting for load all dom element, I am considering #includeNavigation element is under #includeHeader element
<head>
<script src="assets/js/jquery-2.1.3.min.js"></script>
</head>
<body>
<div id="includeHeader"></div>
<script>
$("#includeHeader").load("includes/templates/header.html", function(data){
console.log("header loaded");
$("#includeNavigation").load("includes/templates/navigation.html", function(data){
console.log("navigation loaded");
});
});
</script>
</body>

MMENU jquery plugin doubles all JS scripts

When I'm using mmenu jquery plugin, it doubles all js events and script call, except scripts in head section. What would be the possible solution for this? Any help would be greatly appreciated.
Sorry, but I can't show you full code, it's on working site. Mmenu starts that way in body section:
<script type="text/javascript">
$(document).ready(function() {
$("#my-menu").mmenu();
$("#my-menu").find( ".mm-subopen" ).addClass( "mm-fullsubopen" );
});
</script>
i tried mmenu in my production app and at first it gave me some headaches, but understanding how it works helped me to use it correctly.
Wrap your whole layout in a div without styles (so the website's style remains the same).
Place your menu markup outside your layout (inmediately bellow the body tag).
Add the the plugin at the end of your markup along with the initialization code.
Don't manipulate the inner content of the menu to do actions. Use it's API instead.
After you follow these tips, you should have a structure like this:
<html>
<head> ... </head>
<body>
<nav id="mymenu"> ... </nav>
<div> <!-- whole website in here --> </div>
<script src="js/mmenu.min.js"></script>
<script>
$(document).ready(function() {
var mmenu = $("#mymenu").mmenu();
// do not use code bellow, use the API instead.
// $("#my-menu").find( ".mm-subopen" ).addClass( "mm-fullsubopen" );
var api = mmenu.API(); // exposes methods to open() and close() the menu
});
</script>
</body>
</html>
Hope these setup works for you. It worked for me perfectly in my Meteor app.

AngularJS complains that initialization not defined for jquery

I am getting the below error when loading my page.
Error: initialize is not defined
#http://localhost:8082/js/vendor/jquery-1.11.2.js line 339 > eval:4:3
I want to replace the jqLite with the full version of jquery. I have read several stackoverflow questions on this subject and they imply that all that is required is to load jquery before angularjs. I have done this by simply moving the declaration for jquery above the angular.js. When I do this that is when the above error occurs. It does not give the error when I move the jquery below angularjs but then I cannot use such things as angular.element.
What am I doing wrong?
As far as loading the javascript for each library all I am doing is.
<script type='text/javascript' src="js/vendor/jquery-1.11.2.js"></script>
<script type='text/javascript' src="js/vendor/angular.js"></script>
as far as using jquery instead of lqlite, I am simply trying to use angular.element
var someElement = angular.element('#someelement');
I read a blurb to load jquery before DOMContentLoaded. I am not sure how to do this. I know how to write an event handler for DOMContentLoaded, but what do I do then.
Edited answer: I usually inject my JS script code in the header all inside of an IFFE. You'd also have to make sure you have the ng-app in there to specify the module. Finally I've made sure I actually include the dependent code in the header before my code.
See fiddle here
<head>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script>
(function() {
var testApp = angular.module("testApp", []);
function SomeController($scope) {
console.log('Started controller');
$scope.dirPanelElement = angular.element('#some-panel');
$scope.dirPanelElement.text('set test');
$scope.dirPanelElementText='got "'+$scope.dirPanelElement.text()+'" from panel'
}
testApp.controller("SomeController", SomeController);
})(); // IFFE
</script>
</head>
<body ng-app='testApp'>
<div id="content">
<div style="padding:50px">
<div data-ng-controller="SomeController">
<p align="center">Something</p>
<div id="some-panel"></div>
<div id="some-canvas">{{dirPanelElementText}}</div>
</div>
</div>
</div>
</body>

Uncaught TypeError: undefined is not a function while using jQuery UI

I haven't used jQuery before, and I wanted to use DateTimePicker plugin on my web page.
I downloaded the plugin file and placed them in the same directory as the HTML files.
I directly applied the code at How to use it? in http://xdsoft.net/jqplugins/datetimepicker/.
It threw the following error.
Uncaught TypeError: undefined is not a function pixelcrawler:61 (anonymous function)
My code follows.
<script type='text/javascript' src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="file:///jquery.datetimepicker.css"/ >
<script src="file:///jquery.datetimepicker.js"></script>
<script>
jQuery('#datetimepicker').datetimepicker();
</script>
<div class="container">
<div class="text-center">
<div class="page-header">
<h1>${conf['title']} <small>${conf['description']}</small></h1>
</div>
</div>
<div class="text">
<input id="datetimepicker" type="text" >
.
.
.
.
.
I could not figure out what the problem was. I have tried many other seemingly likely options, but it just did not work either.
(The ${} tags are used for the Mako template language. I am using Cherrypy.)
UPDATE:
I figured out the source of the problem.
It's from jQuery('#datetimepicker').datetimepicker();.
When tested, the datetimepicker() function was undefined. Maybe the way I imported the library was wrong?
jQuery(document).ready(function(){
jQuery('#datetimepicker').datepicker();
})
I don't know your file-structure. I never include local files like this as I use relative URLs from the start rather than having to change everytime I'm ready to use the code, but it's likely one of the files isn't being loaded in. I've included the standard datepicker below using Google CDN's jQuery UI. Does your console log any resources not found?
I think your jQuery is loaded OK, because it's not telling you jQuery is not defined so it's one of your files.
BTW, PHP gets the home URL:
$home="http://" . $_SERVER['HTTP_HOST'].'/';
Demo code datepicker, jQuery UI:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('#datetimepicker').datepicker();
})
</script>
<input id="datetimepicker" type="text">
This is about the HTML parse mechanism.
The HTML parser will parse the HTML content from top to bottom. In your script logic,
jQuery('#datetimepicker')
will return an empty instance because the element has not loaded yet.
You can use
$(function(){ your code here });
or
$(document).ready(function(){ your code here });
to parse HTML element firstly, and then do your own script logics.
use jQuery.noConflict()
var j = jQuery.noConflict();
j(document).ready(function(){
j('#datetimepicker').datepicker();
})
For my situation, it was a naming conflict problem. Adding $J solves it.
//Old code:
function () {
var extractionDialog;
extractionDialog = $j("#extractWindowDialog").dialog({
autoOpen: false,
appendTo: "form",
height: "100",
width: "250",
modal: true
});
$("extractBomInfoBtn").button().on("click", function () {
extractionDialog.dialog("open");
}
And the following is new code.
$j(function () {
var extractionDialog;
extractionDialog = $j("#extractWindowDialog").dialog({
autoOpen: false,
appendTo: "form",
height: "100",
width: "250",
modal: true
});
$j("extractBomInfoBtn").button().on("click", function () {
extractionDialog.dialog("open");
});
});
Hope it could help someone.
Usually when you get this problem, it happens because a script is trying to reference an element that doesn't exist yet while the page is loading.
As richie mentioned: "The HTML parser will parse the HTML content from top to bottom..."
So you can add your JavaScript references to the bottom of the HTML file. This will not only improve performance; it will also ensure that all elements referenced in your script files have already been loaded by the HTML parser.
So you could have something like this:
<html>
<head>
<!-- Style sheet references and CSS definitions -->
</head>
<body>
<!-- HTML markup and other page content -->
<!-- JavaScript references. You could include jQuery here as well and do all your scripting here. -->
</body>
</html>
You may see if you are not loading jQuery twice somehow. Especially after your plugin JavaScript file loaded.
I has the same error and found that one of my external PHP files was loading jQuery again.
The issue because of not loading jquery ui library.
https://code.jquery.com/ui/1.11.4/jquery-ui.js - CDN source file
Call above path in your file.
And if you have this problem in slider or slideshow you must use jquery.easing.1.3:
<script src="http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js"></script>
I had trouble getting selectable to work with ASP.NET. It turns out I wasn't properly including everything, but this gentleman made it foolproof: Three steps to use jQuery UI in ASP.NET MVC 5.
I don't think jQuery itself includes datetimepicker. You must use jQuery UI instead (src="jquery.ui").

Is this javascript, and where should I place it

I came accross this html multiple file upload tutorial: http://robertnyman.com/2010/12/16/utilizing-the-html5-file-api-to-choose-upload-preview-and-see-progress-for-multiple-files/
I'm new to web programming enough to not being able to understand how to make a code from the two sections of the 'complete code' in this tutorial, which basically are:
A. Some html code:
<h3>Choose file(s)</h3>
<p>
<input id="files-upload" type="file" multiple>
</p>
<p id="drop-area">
<span class="drop-instructions">or drag and drop files here</span>
<span class="drop-over">Drop files here!</span>
</p>
<ul id="file-list">
<li class="no-items">(no files uploaded yet)</li>
</ul>
B. And some javascript:
(function () {
var filesUpload = document.getElementById("files-upload"),
dropArea = document.getElementById("drop-area"),
fileList = document.getElementById("file-list");
function uploadFile (file) {
[etc]
I recognize the code, but I don't understand where a part of code beginning with (function () is supposed to go into my code.
So my question is: how should the javascript part be placed in my code.
[Edit]
Thanks for your complementary answers!
Either just before the </body> tag, between a <script type="text/javascript"></script> tag like this:
<body>
<!-- other stuff -->
<script type="text/javascript">
(function () {
// this is your function's core
})();
</script>
</body>
Or within the <head></head> tag, also between a <script type="text/javascript"></script>, but you have (probably) to wait until the DOM correctly loaded. For example, using jQuery:
<head>
<!-- other stuff -->
<script type="text/javascript">
$(function() {
(function () {
// this is your function's core
})();
});
</script>
</head>
Or even within an external JavaScript file, where you'll also have (probably) to wait until the DOM correctly loaded. For example, once again using jQuery:
file myScripts.js
$(function() {
(function () {
// this is your function's core
})();
});
file myDocument.html
<head>
<!-- other stuff -->
<script type="text/javascript" src="/path/to/myScripts.js"></script>
</head>
Javascript is placed inside onClick, onMouseOver, etc. attributes, as well as inside <script type="text/javascript"> tags.
They can be anywhere inside the <head> or <body> tags (place it after the elements you are accessing, so that they load).
w3 Schools has a Javascript reference to get you started.
Create a file with .js extension so yourFile.js.
Put your java-script code in it...
At the end of HTML file place this inside:
<script src="yourFile.js"></script>
Make sure your js is in the same directory as is your html...
Just put the javascript inside <script></script> tags after your upload form.
The post you linked to has a complete working demo of the code it describes which can be found here:
http://robertnyman.com/html5/fileapi-upload/fileapi-upload.html
A good way to experiment with this kind of code snippet is to paste the required section into a tool like JSFiddle
Since the code includes getElementById but nothing like window.onload or any other deferring tactic, it MUST be placed AFTER the form you want it to affect. To be on the safe side, you can place it in a <script> tag immediately before </body>.

Categories