I'm working on a ASP.NET Core project using Bootstrap 4 and I have some Bootstrap Modals that I want to show in multiple views.
These Modals have some Javascript functions for internal elements, like Buttons and Inputs.
What is the correct approach to load these Modals (with their Javascript) in multiple views?
I figured I'd use PartialViews, but I don't know where to put the Javascript code (I know that putting it in PartialViews is a bad practice).
Create a seperate JS file and reference it on the bottom of every page that uses this partial view, so the script does not block the page-rendering.
Alternatively you could create a layout file which contains both the modals HTML and JS, and let your views inherit from this. Although I would advise against this approach due to the composition over inheritance principle.
Tag helpers might be better used for this, here's an example of a bootstrap modal tag helper ModalTagHelper
Then if you put this in your _ViewImports file:
#using AssemblyNameWithTagHelpers
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#addTagHelper "*, AssemblyNameWithTagHelpers"
You can use a tag helper like this:
<modal id="simpleModalFromAnchor" title="Modal Title">
<modal-body>
<h4>Something happened</h4>
<p>Something happened</p>
</modal-body>
</modal>
With the javascript, put it in a separate js file and reference it from each page you use the modal in, better yet, put it in a bundle with other well used components and include it in the bottom of your _Layout file
Related
I use https://jquerymodal.com/ package for modal dialogues, it works out great when I am in need of editing small forms, which I embed in the same document.
But issue is; I also use jquery-ui-datepicker and Chosen package (https://harvesthq.github.io/chosen/) for my forms. It seems that javascript does not work inside modal.
As noted on jquerymodal.com, i have tried both using embedded in html and ajax loading as below. I couldn't get it working. Below route returns a view where I have a form partial. (I tried with extending layout a file, where I have proper links to my js files..., this didn't work either).
<a href="{{route('form_edit',['projectid' => $project->id])}}" rel="modal:open">
Load Edit Form
</a>
Is this possible or should i be trying out something different for this?
In an ASP.NET Core app, I've a dashboard with widgets. Every widget has its own PartialViews, so the full page is generated in the following way:
-Layout.cshtml
--Dashboard.cshtml
--- Widget1.cshtml
--- Widget2.cshtml
Following best practices according to fast page load times, JavaScript is loaded before the closing </body> tag in Layout.cshtml. After that, there is a section for custom JS, which I commonly use to initiate objects on page load. So this section looks like this:
<script asp-append-version="true" type="text/javascript" src="~/clientscript/page.min.js"></script>
#RenderSection("Js", required: false)
In my Views, which are using the Layout.cshtml as layout (in this example, its Dashboard.cshtml), I can define a section like
#section Js {
// Js Code here
}
which is rendered after the script tag containing all script files. So I can be sure, that all dependencies like jQuery or custom classes are avaliable here.
But I also need to do this in widgets like Widget1.cshtml for example. The problem is: I load the PartialView Widget1.cshtml in Dashboard.cshtml. In the documentation is written, that this is not possible:
If you declare a Razor section in a partial view, it will not be visible to its parent(s); it will be limited to the partial view.
But that's exactly what I need. Is there a way to work around this limitation? Shortly, the goal is to inject JavaScript from a PartialView to the LayoutView, with an regular View between them.
The only way I know is the usage of setInterval() with a low interval like 50ms, and check there if jQuery or some of my custom class is defined in a loop until they are. Its a JS solution yes. But it makes it possible to include the script-block directly in the PartialView without making usage of sections. It fits well when you depend on a single variable like jQuery.
But I need to wait for custom classes to get loaded. They're included after jQuery. So writing a generic function like waitForTypeLoaded(type, callback) is not possible. It would cause me to write always the raw setInterval() code, which seems not a smart solution for me.
Something I did to get my scripts to run after Jquery was done loading was in my Partial Views and View Components I used the "DOMContentLoaded" event to load all my jQuery js script after the page was done loading. That way I could defer the Load of jQuery and Still Have jQuery code on my pages.
<script>
window.addEventListener('DOMContentLoaded',
function() {
$('body')....
});
</script>
Your problem can be solved as mentioned in my answer to this post:
How to render scripts, generated in TagHelper process method, to the bottom of the page rather than next to the tag element?
To sum up, you can create a pair of tag helpers, one that can be located in a partial view and just stores its content in a temporary dictionary, and the other that renders the content at the appropriate position (e.g. in the layout page). I use it extensively to render small dynamically created scripts as the final scripts of the body.
Hope it helps.
Honestly, I would make one step back and look at architecture once again if you have such dilemmas.
Why not add to required scripts which will be used on a couple of views/partial views to the main layout? In ASP.NET MVC you can use bundling mechanism (or you can write our own) - minify and bundle them with other required. It won't be heavy...
Your approach looks like unnecessary complicated.
I have the following problem.
I have a typo3 page without any template I made by myself, but it gets in some way the style and the behavior of the other pages (I mean navigation, footer and so on). Now I have written some HTML inside the page by creating an HTML element.
In this HTML element, I included some js-code, which uses jQuery. The problem is, that the page loads the jquery at the footer and my scripts are loading before (in the HTML element). So my script does not recognize jQuery. How can I add my scripts at the whole end of the page? I know, that it has something to do with templates, but when I create a new template for the page, the whole content disappears.
Would be nice to get any help.
Cheers,
Andrej
It is usually good practice to read all your JS from a single file placed in the footer of the page. Add this to the setup section of your page template:
page.includeJSFooter.scripts = fileadmin/js/scripts.js
Then remove the JS from the HTML template and put into this file. This file could hold all your custom JS and possibly even all the libraries you use on the page (if you are not loading them from a CDN).
Bonus: the JS doesn't have to be re-loaded on every page view but can be read from cache.
For reference: https://docs.typo3.org/typo3cms/TyposcriptReference/Setup/Page/Index.html#includejsfooter-array
I hope by template you mean a template record where you store your TypoScript? Otherwise this answer is not what you are looking for. :)
You can just add an extension template on your page that only adds to the rest of the TypoScript but does not override anything. To do so, go to the template module, choose "info/modify" in the dropdown at the top and use this button
Explanation: an extension template has the checkboxes for clearing the constants and the setup not checked and will not mess with the rest of your site's TypoScript:
I'm new to angular development. I have been using a few paid angular admin themes. In all of them, developers have only added ng-view and ng-class attribute to index.html. I just want to know how to add a sidebar navigation and a footer to every page without using any ng-include.
If you do not want to use ng-include, you can put your HTML directly in the index.html. That is called a layout template, which is the view that contains the common elements along your application.
In summary, everything in index.html outside the ng-view element is going to appear in every page (as long as you use any module such as angular-route for routing within the same original HTML document (e.g. index.html)).
I would recommend you to follow the official AngularJS tutorial if you are new to this framework. Also, ng-book by Ari Lerner is a must-read on this topic.
I have some HTML files, and each one of them I want to partially render in another HTML file, for example header.html and footer.html in order to observe DRY concept.
HTML files should look like this:
<!--render header.html-->
<div>
Content
</div>
<!--render footer.html-->
How can I do that?
If you're just using plain HTML and Javascript, you could include jQuery and use an AJAX request to load the contend of another HTML page in your main page.
Have a look at the jQuery 'load()' function here:
http://api.jquery.com/load/
Assuming your have the following html:
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
your usage would look something like this:
$('#header').load('header.html');
$('#footer').load('footer.html');
Here's a link (first one from Google I might add) that explains how to do this in various languages.
Also note that some IDEs take care of this for you. Dreamweaver being one example; in ASP.NET there are master pages; and so on.
PHP:
<?php
require($DOCUMENT_ROOT . "path to file/include-file.html");
?>
ASP:
<!--#include file="path to file/include-file.html"-->
JS:
JavaScript is another way to include HTML within the pages of your
site. This has the advantage of not requiring server-level
programming. But it's a little more complicated than the server-level
include methods.
Save the HTML for the common elements of your site to a JavaScript
file. Any HTML written in this file, must be printed to the screen
with the document.write function.
Use a script tag to include the
JavaScript file on your pages.
<script type="text/javascript" src="path to file/include-file.js">
Use that same code on
every page that you want to include the file.
PLEASE NOTE that the JS version is NOT ideal.
1. JS may be disabled or unavailable in the browser.
2. The page won't be rendered/loaded all at once.
Also, I don't think DRY really counts for this one. Consider using an IDE that will create page templates for you (like Dreamweaver for example).
If you are brave enough (and a little bit old fashioned) and you can't use any of the above, consider using an iframe for your content:
<html>
<body>
<div>my header</div>
<iframe src="mycontent.html" />
<div>my fooder</div>
</body>
</html>
DISCLAIMER
I would rather cut off my own hands than implement the iframe or JS approach. Give deep consideration towards whether you actually NEED to do this.
If you are looking for a client side only solution that is html/js only you should have a look at AngularJS and its ngInclude syntax.
http://docs.angularjs.org/#!/api/ng.directive:ngInclude
If you are using server-side programming, you can use server-side include else if your host file is an HTML file then you can use html SCRIPT tag to include the header.html and footer.html files. Though, am not sure as to what do you really mean by partially rendering HTML file?
As others said, it looks like it can't be done with HTML alone. Another way it could be done on the server-side, if you are using Java, is with Thymeleaf.
For example, adding a main menu on every page with
<div th:replace="fragments/mainmenu.html"></div> . Then mainmenu.html could just contain a bunch of divs. The fragment doesn't need to be a full HTML page.