Single CSS from appasset.php per page in yii2 - javascript

I am using the yii2 framework and the following code in appasset.php:
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [ 'css/site.css', 'css/country.css', 'css/admin/one.css', 'css/fg/two.css' ];
public $js = [ ];
public $depends = [ 'yii\web\YiiAsset', 'yii\bootstrap\BootstrapAsset', ];
My page pulls in all of the CSS files listed, but I only want one.css in this page, and to use the other CSS files in other pages.
How can I prevent these other CSS files from appearing in this page? Or - is it possible to create a new appasset.php file for a single php page?

Each specific situation should have its own AssetBundle.
You just create as many as you need and include them in the relevant view file:
Existing one:
class AppAssets extends \yii\web\AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = ['css/site.css', 'css/country.css', 'css/fg/two.css'];
...
}
Additional one:
class AdminAssetBundle extends \yii\web\AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = ['css/admin/one.css'];
public $depends = ['AppAssets'],
}
(Please add namespaces where necessary, I left those out)
As said: Then just include the one you need in the view that is relevant.
ie. in your admin views you add: AdminAsset::register($this);
Because of the depends, those views will automatically include your AppAssets bundle.
If your AppAssets is the one from the yii app distribution (added by default), it is probably already being registered in the /views/layouts/main.php-file.
That means that it is not required to be defined as a dependency.
I do consider it a good practice to keep the dependencies clear (if your admin one.css file actually depends on the ones from AppAssets, if not remove the $depends alltogether).
Yii is smart enough to only include each asset bundle only once anyway.

Related

How to architect ASP.Net app to load Controller specific JS

I have an asp.net app with a site.js which is getting lengthy. What is the proper way to architect the file structure so that /home routes will load a home.js file and /product routes will load a routes.js file?
Ideally I would like to keep all the js files in the wwwroot folder and not next to the views or within them so I can minify them with the compiler
you can create an extension method for Html helper and call that on _Layout.cshtml as #Html.RenderControllerJs(Url); so that it gets called every time and inject the respective js.
public static class HtmlHelperExtentions
{
public static IHtmlContent RenderControllerJs(this HtmlHelper html, UrlHelper urlHelper)
{
var env = html.ViewContext.HttpContext.RequestServices.GetService<IHostEnvironment>();
var controllerName = html.ViewContext.RouteData.Values["Controller"].ToString().ToString();
var jsFileRelativePath = Path.Combine("<folder_path_for_all_controller_js>", $"{controllerName}.js");
var controllerJsFilePath = Path.Combine(env.ContentRootPath, jsFileRelativePath);
if (File.Exists(controllerJsFilePath))
{
return html.Raw(
$"<script type=\"text/javascript\" src=\"{urlHelper.Content(Path.Combine("~", jsFileRelativePath))}\"></script>");
}
return new HtmlString("");
}
}
You can also write custom logic specific to any controller. You have full control now.

Including Css and Js files programatically in .Net Core Layout View

When we were using standart .net platform we were able to include css and js files by action and controller name by a code like this;
string scriptSource = Url.Content(string.Format("~/js/page/{0}/{1}.js", controllerName, actionName));
if (System.IO.File.Exists(Server.MapPath(scriptSource)))
{
<script type="text/javascript" src="#scriptSource"></script>
}
We were putting these codes in Layout and It was working when you name js folder same as controller name and js file same as action name..
For a while ago I upgraded project to .Net Core(2.1) and made dependecy injection to BaseController to get Server.MapPath value, but I couldn't reach from _Layout view to the BaseController or codebehind to get Server.Mappath.. If any of you could succeeded this please let me know.
In ASP.NET Core, we don't use Server.MapPath. We want to use IHostingEnvironment instead.
In the file _Layout.cshtml, you could try:
#using Microsoft.AspNetCore.Hosting
#inject IHostingEnvironment environment
#{
string path = string.Format("js/page/{0}/{1}.js", controllerName, actionName);
}
#if (System.IO.File.Exists(System.IO.Path.Combine(environment.WebRootPath, path)))
{
<!-- file exist here... -->
}
In the controller, you can pass it via constructor:
public class HomeController : Controller
{
private readonly IHostingEnvironment _environment;
public HomeController(IHostingEnvironment environment)
{
_environment = environment;
}
public IActionResult Index()
{
string path = System.IO.Path.Combine(_environment.WebRootPath, "js/page/...");
return View();
}
}

How to organize JavaScript in Yii project

I write project using Yii.I would like to receive advice on how to organize my JavaScript.I thought about several options:
Put all code in one file (app.js), create for each feature moduls and attach it to each page of project.But problem is that not all feature required in all pages and so in this case I have to load useless code and it is difficult to navigate among hundreds of lines.(I know that I can write in separate files and then "compile" all in one, but it does not solve problem of excess code)
Create for each feature separate file and manage it loading through Yii(attach only necessary files to page). But some feature require only couple lines of code and it seems irrational to create file for that.
You could use a mixing of Asset and layout
In a proper layout stored inside your_app\views\layouts\your_asset_filename.php
you could register a specific asset
use your_app\assets\YourAsset;
//use common\models\UserParam;
//use common\models\LandScope;
/* #var $this \yii\web\View */
/* #var $content string */
YourAssest::register($this);
?>
In your_app\asset you could configure the js files you needs
class YourAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/site.css',
........
];
public $js = [
'your_js1.js',
'your_js2.js',
....
];
public $jsOptions = ['position' => \yii\web\View::POS_HEAD];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
and last your controller/action you can set the layout you need for each render
public function actionMyAction()
{
$this->layout = 'your_asset_filename';
...
return $this->render('your_view',[ ....]);
}

How define widget assets file in yii2?

I try to create a widget in yii2 in this folder:
basic/components/input/
and create "assets" and "view" in that directory.
I created my widget and it works but i need add "CSS" an "JS" file to my widget.
in yii1 can use assets in widget folder but i can't do that in yii2
any body can help me?
I found my Answer.
you should create a AssetBundle in your widget dir like this:
/**
* Define Assets of inout tag widget
*/
namespace app\components\InputTag;
class InputTagAsset extends \yii\web\AssetBundle
{
public $sourcePath = "#app/components/InputTag/assets";
public $css = [
'css/xx.css',
];
}
and then call your AssetBundle in your widget file in init() method like this:
public function init(){
parent::init();
InputTagAsset::register($this->view);
}
and put your files in assets folder.

Vaadin7 jQuery UI integration

Vaadin 7 supports custom javascript. But my question is if we want to integrate jQuery-ui with vaadin7, how can we add jQuery-ui css files. At the moment #Javascript supports adding javascript only. If we wanna add css, we have add that as sass style.
To add jQuery (or any other javascript library) to a Vaadin 7 application, follow these easy steps:
First Create a Vaadin project either using your favorite IDE or the vaadin maven archetype (or both). Create a new class that extends from VaadinServlet, and override the servletInitialized method:
import javax.servlet.ServletException;
import com.vaadin.server.BootstrapFragmentResponse;
import com.vaadin.server.BootstrapListener;
import com.vaadin.server.BootstrapPageResponse;
import com.vaadin.server.ServiceException;
import com.vaadin.server.SessionInitEvent;
import com.vaadin.server.SessionInitListener;
import com.vaadin.server.VaadinServlet;
public class TestJqueryVaadinServlet extends VaadinServlet {
#Override
protected void servletInitialized() throws ServletException {
super.servletInitialized();
getService().addSessionInitListener(new SessionInitListener() {
#Override
public void sessionInit(SessionInitEvent event) throws ServiceException {
event.getSession().addBootstrapListener(new BootstrapListener() {
#Override
public void modifyBootstrapPage(BootstrapPageResponse response) {
// With this code, Vaadin servlet will add the line:
//
// <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" />
//
// as the first line inside the document's head tag in the generated html document
response.getDocument().head().prependElement("script").attr("type", "text/javascript").attr("src", "//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js");
}
#Override
public void modifyBootstrapFragment(BootstrapFragmentResponse response) {}
});
}
});
}
}
Then add the reference to the servlet in your web.xml or annotate the class with the #WebServlet annotation.
And then Create your jQuery snippet and invoke it using the JavaScript class, for example:
public class MyVaadinUI extends UI {
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
Label label = new Label("This will fade-out once you click the button");
Button button = new Button("Hide Label");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
JavaScript.getCurrent().execute("$('.v-label').animate({opacity: 0.0}, 3000);");
}
});
layout.addComponent(label);
layout.addComponent(button);
}
}
Including style sheets or JavaScript files in your add-ons or as a part of your application can now be done by adding a #StyleSheet or #JavaScript annotation to a Component or Extension class. Each annotation takes a list of strings with URLs to the resources that should be loaded on the page before the framework initializes the client-side Component or Extension.
The URLs can either be complete absolute urls (e.g."https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js") or relative URLs (e.g. "redbutton.css"). A relative URL is converted to a special URL that will download the file from the Java package where the defining class is located. This means that e.g. #StyleSheet({"redbutton.css"}) on the class com.example.RedButton will cause the file com/example/redbutton.css on the classpath to be loaded in the browser. #JavaScript works in exactly the same way
#!java
#StyleSheet("redbutton.css")
public class RedButton extends NativeButton {
public RedButton(String caption) {
super(caption);
addStyleName("redButton");
}
}
In this simple example, the RedButton component just adds a
redButton
style name to a normal
NativeButton
. redbutton.css is located in the same folder as RedButton.java and has this content:
#!css
.redButton {
background-color: red;
}
This new mechanism makes it very easy to include style sheet or JavaScript files with add-ons and automatically load them in the browser when the add-on is used.
Second and my favorite way:
you can also use the #Stylesheet and #Javascript annotations. its much simpler.
#StyleSheet({
/*
* JQuery UI
*/
"vaadin://jquery/jquery-ui-1.9.2.custom/css/ui-darkness/jquery-ui-1.9.2.custom.min.css",
})
#JavaScript({
/*
* JQuery
*/
"vaadin://jquery/jquery-1.11.1.min.js",
/*
* JQuery UI
*/
"vaadin://jquery/jquery-ui-1.9.2.custom/js/jquery-ui-1.9.2.custom.min.js",
})
public class MyUI extends UI {
...
}

Categories

Resources