jQuery only seems to be working in Layout.cshtml - javascript

I am currently working on the basics of a .NET C# Razor page application running the following:
Razor pages
.NET 5/C#
jQuery v3.5.1
Bootstrap v4.3.1
My current issue is that jQuery (and plain JS) are only working in the Layout.cshtml file, I have tried the following:
Script tags in the head of _layout.cshtml
Script tags at the bottom of the body of _layout.cshtml
Wrapping the jQuery in #section scripts{}
At this stage I am fairly sure it is just a case of, it needs to be setup in a very particular way in .NET5, but I really have no more clues
Bottom of _Layout.cshtml
</header>
<div class="container-fluid">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#RenderSection("Head", required: false);
#RenderSection("Scripts", required: false);
</body>
</html>
Bottom of the index.cshtml file
#section scripts {
<script>
$(document).ready(function () {
$(".btn-reply").click(function (event) {
alert("it works");
});
});
</script>
}

Rather frustratingly this turned out not to be anything JS related at all, in actually fact this was down to main div with the class of row having a z-index of -1, no idea how this came to be, I don’t recal having set this, but if I did I whole apologise to anyone who took the time to read this.

Related

Bootstrap popover works on second load

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();">

formDiv.dialog is not a function [duplicate]

I am having an issue getting a dialog to work as basic functionality. Here is my jQuery source imports:
<script type="text/javascript" src="scripts/jquery-1.9.1.js"></script>
<script type="text/javascript" src="scripts/jquery-ui-1.11.1.js"></script>
<script type="text/javascript" src="scripts/json.debug.js"></script>
Html:
<button id="opener">open the dialog</button>
<div id="dialog1" title="Dialog Title" hidden="hidden">I'm a dialog</div>
<script type="text/javascript">
$("#opener").click(function() {
$("#dialog1").dialog('open');
});
</script>
From the posts around seems like as a library import issue. I downloaded the JQuery UI Core, Widget, Mouse and Position dependencies.
Any Ideas?
Be sure to insert full version of jQuery UI. Also you should init the dialog first:
$(function () {
$( "#dialog1" ).dialog({
autoOpen: false
});
$("#opener").click(function() {
$("#dialog1").dialog('open');
});
});
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css" />
<button id="opener">open the dialog</button>
<div id="dialog1" title="Dialog Title" hidden="hidden">I'm a dialog</div>
if some reason two versions of jQuery are loaded (which is not recommended), calling $.noConflict(true) from the second version will return the globally scoped jQuery variables to those of the first version.
Some times it could be issue with older version (or not stable version) of JQuery files
Solution use $.noConflict();
<script src="other_lib.js"></script>
<script src="jquery.js"></script>
<script>
$.noConflict();
jQuery( document ).ready(function( $ ) {
$("#opener").click(function() {
$("#dialog1").dialog('open');
});
});
// Code that uses other library's $ can follow here.
</script>
If you comment out the following code from the _Layout.cshtml page, the modal popup will start working:
</footer>
#*#Scripts.Render("~/bundles/jquery")*#
#RenderSection("scripts", required: false)
</body>
</html>
Change jQueryUI to version 1.11.4 and make sure jQuery is not added twice.
I just experienced this with the line:
$('<div id="editor" />').dialogelfinder({
I got the error "dialogelfinder is not a function" because another component was inserting a call to load an older version of JQuery (1.7.2) after the newer version was loaded.
As soon as I commented out the second load, the error went away.
Here are the complete list of scripts required to get rid of this problem.
(Make sure the file exists at the given file path)
<script src="#Url.Content("~/Scripts/jquery-1.8.2.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.24.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript">
</script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript">
</script>
and also include the below css link in _Layout.cshtml for a stylish popup.
<link rel="stylesheet" type="text/css" href="../../Content/themes/base/jquery-ui.css" />
I had a similar problem and in my case, the issue was different (I am using Django templates).
The order of JS was incorrect (I know that's the first thing you check but I was almost sure that that was not the case, but it was). The js calling the dialog was called before jqueryUI library was called.
I am using Django, so was inheriting a template and using {{super.block}} to inherit code from the block as well to the template. I had to move {{super.block}} at the end of the block which solved the issue. The js calling the dialog was declared in the Media class in Django's admin.py. I spent more than an hour to figure it out. Hope this helps someone.

jQuery plugins conflict and script declaration order

I'm new to web development, and was having issues with two plug-ins. I already found a workaround to solve it, but I'm not convinced at all about what I did, so I ask you guys if you can enlighten me on what is this about.
The page in question uses SlimScroll and DataTables plugins. At first, I had an HTML file like this one.
<body>
<!-- STUFF -->
<!-- SCRIPTS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="plugins/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="plugins/slimScroll/jquery.slimscroll.min.js" type="text/javascript"></script>
<script src="plugins/DataTables/datatables.min.js" type="text/javascript"></script>
<script src="assets/scripts/tablas.js" type="text/javascript"></script>
<script src="assets/scripts/general.js" type="text/javascript"></script>
At the bottom, general.js is used to handle click events and other stuff, and tablas.js has the code that picks up a file with data and displays it in DataTables. The relevant code from general.js:
$(document).ready(function() {
$('#contenedor-menu').slimScroll({
height: '100%'
});});
And the code for tablas.js:
$(document).ready(function() {
$('#tablita').DataTable( {
"ajax": 'data/COut2.txt',
} );});
With this structure, when I load the page, SlimScroll fails with the message in the console: "TypeError: $(...).slimScroll is not a function"
Then after touching around, I switched the order of the scripts in the HTML file. I put datatables first and then slimscroll.
<script src="plugins/DataTables/datatables.min.js" type="text/javascript"></script>
<script src="plugins/slimScroll/jquery.slimscroll.min.js" type="text/javascript"></script>
And now it works ok, with no errors.
Could somebody please explain to me what's going on?
Thanks in advance!
The use of multiple $(document).ready(function() { } is the main cause of this issue. There should be only one Document Ready event handler.
You may try using the pageLoad() function or onLoad() events
Not positive but it is usually best practice to put the scripts you absolutely need before everything else in the head. This is so that the content of the page does not finish loading until all the dependencies have been loaded first.
By reordering your scripts you may have a solution that will only work some of the time.
Put all the scripts you need to load in the head and your general.js script at the end of your body element.

Using Ember.js for Single Page Website (not really a web app)

I just want to try using Ember.js for a website I am doing (Disclaimer: I am a Java web developer, GWT).
So far what I have tried is to slap the whole body tag code into like this
<body>
<script type="text/x-handlebars">
<!-- The whole page -->
</script>
</body>
Now, I just want to take advantage of Ember.js stuff like components, models and validation for my website.
Here's a run down of the dependencies involved:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js" type="text/javascript"></script>
<script src="js/vendor/modernizr-2.6.2.min.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<!-- Ember -->
<script src="js/libs/handlebars-v3.0.0.js"></script>
<script src="js/libs/ember-template-compiler-1.10.0.js"></script>
<script src="js/libs/ember-1.10.0.debug.js"></script>
<script src="js/app.js"></script>
app.js
App = Ember.Application.create();
App.Router.map(function() {
});
The thing is, when I put the body into a x-handlebars script the jQuery plugins (like bxslider, carousel, etc.) that used to work would not work with the stuff that was inside the script tag.
What could be wrong with my approach?
What is rendered in your <script type="text/x-handlebars">Script</script> is being rendered after your JQuery code has run. You can fix this by modifying using the didInsertElement event in your view or component to run any code that is needed to initialize the elements in the view that was rendered.
didInsertElement: function() {
this.$().DoStuff();
}
There are a number of other questions on StackOverflow - including, for instance, this one - addressing similar issues, so you should be able to adapt their approaches.

Laravel 4: How to register a script that goes with a partial view so that it loads after its javascript dependencies?

Have a Laravel 4 web site that uses a layout where jquery, boostrap, etc are loaded at the bottom of the page:
<html>
<body>
<!-- stuff -->
<script src="...jquery, bootstrap, etc..."></script>
</body>
</html>
In some of the pages on the site I'm also using a partial view, and the view uses a script that depends on the bottom-of-the-page scripts. To keep things clean I'd like for the script to be part of the view file itself so that whenever the view is included its corresponding javascript is included as well. However, when the script is part of the view, it fails because the script tags will come before the dependencies at the bottom of the page.
Is there any nice way using something like blade's #yield and #section directives to keep the script in the same file as the view, but have it load in a section of the layout below the javascript dependencies? I don't believe I can use #yield/#section because the partial does not #extend any layout. It is simply #included in the views that need it.
So what I'd like in the end is something like:
partial.blade.php:
<div><!-- partial's html stuff --></div>
<script><!-- partial's script stuff --></div>
view.blade.php:
#extends('layout')
#section('content')
#include('partial')
#stop
layout.blade.php
<html>
<body>
#yield('content')
<script><!-- jquery, bootstrap, etc. --></script>
</body>
</html>
final html output:
<html>
<body>
<div><!-- partial's html stuff --></div>
<script src="...jquery, bootstrap, etc..."></script>
<script><!-- partial's script stuff --></div>
</body>
</html>
Obviously, the easy answer is to load the dependencies in the <head> tag, but I'd like to know if it's possible to avoid this.
You can try this. I've tested it and i believe it works.
LAYOUT
<html>
<body>
#yield('content')
<script>'Scripts From Layout'</script>
#yield('scripts')
</body>
</html>
VIEW
#extends('layout')
#section('content')
#include('partial')
#stop
#section('scripts')
#include('partial')
#stop
PARTIAL
#section('content')
<div>DIV From Partial</div>
#stop
#section('scripts')
<script>'Scripts From Partial'</script>
#stop
OUTPUT
<html>
<body>
<div>DIV from partial</div>
<script>'Scripts From Layout'</script>
<script>'Script From Partial'</script>
</body>
</html>
Define a section called 'scripts' in your layout that comes after all necessary JS libraries have been loaded.
<script src="..."></script>
#yield('scripts')
Your views can use #section('scripts') to put inline JS into the section.

Categories