How to dynamically import css with backbone? - jquery-mobile

I'm developing a app, using backbone, underscore, and jquerymobile. Following jqmobile's way, I have an index page which loads every visited page in special divs tags, flagged with the attribute data-role="page". For each page, i have its corresponding style file (or code snippet embedded in a style html tag). My problem is that the names of my stylable stuff started to collide. Other thing is that I would not like unnecessary style files loaded for each page. Is there any way of dynamically import only the required css for the current page?

I am accomplishing exactly what you ask using RequireJS and the RequireCSS plugin.
Here is a snippet from one of my views:
define([
'jquery',
'underscore',
'backbone',
'views/company/form',
'text!templates/company/company.html',
'css!../../../css/company/company',
], function($, _, Backbone, Form, pageTemplate) {
var Page = Backbone.View.extend({
...
});
return Page;
});
Line 7, 'css!../../../css/company/company' is where the css file becomes a requirement for loading this view.
Once the company.css stylesheet is loaded, it's in the browser even when other "pages" load because there are no actual page refreshes. Thus I have my main page views toggle a class on the <html> element:
// remove any old route-* classes existing on the html element
$('html').removeClassRegEx(/^route-.*/);
// add in the company's top-level class name
$('html').addClass('route-company');
And all my page-specific styles for the company page are scoped to the .route-company class.
You can find the jQuery plugin removeClassRegEx here.

One way of doing that is with jquery (which you 90% are already using with backbone), and its load or get ajax functions, or whatever, plus callbacks.
Then you can call such functions from your backbone app if you need to, and simply inject that css inside <style> tags into your document, as a template.
Or I think there are also specialized jquery functions.
Another way I can think of doing that would be with require.js and it's plugins (it has text plugin, I believe, which will also enable you to load your javascript templates).

Related

How to change the theme of an existing application developed using jquery-mobile?

I am building an application using jquery mobile and phone gap. As I am about to start the application, have a doubt on how to change the theme of an application on the fly or with minimum changes involved so that I can use the same app with different themes for different client.
Please let me know is there a configuration or common place available to update/change the theme of an entire application at any moment during the development.
EDIT: sorry to confuse a bit, the question is with how to switch between the themes provided by default by jquery mobile like a, b, c, d and e without doing any or much code change.
Thanks.
jQuery Mobile has 3 different CSS files, you can get them when you download whole package.
jQuery Mobile CSS file
jQuery Mobile Structure CSS file
jQuery Mobile Theme CSS file
If you want to use different themes all you need to do is use second and third mentioned file. Structure CSS holds jQuery Mobile structure CSS and it is a backbone of whole structure. What you need to change is jQuery Mobile theme CSS file. This is a file you get when you create a new theme.
On the other hand jQuery Mobile will have several more CSS files but logic is the same. If you download jQuery Mobile from this link: http://jquerymobile.com/
You will find these files:
jquery.mobile.external-png-1.4.2.min.css
jquery.mobile.icons-1.4.2.min.css
jquery.mobile.inline-png-1.4.2.min.css
jquery.mobile.inline-svg-1.4.2.min.css
jquery.mobile.structure-1.4.2.min.css
jquery.mobile.theme-1.4.2.min.css
jquery.mobile-1.4.2.min.css
If you want to use customized themes you will need to remove jquery.mobile-1.4.2.min.css and jquery.mobile.theme-1.4.2.min.css. Theme builder will give you new jquery.mobile.theme-1.4.2.min.css file, or even if you download it from somewhere you will get alternative jquery.mobile.theme-1.4.2.min.css file.
Update
Working example: http://jsfiddle.net/Gajotres/LfLFm/
JavaScript:
$(document).on('pagebeforecreate', '#index',function (e, ui) {
$(this).removeClass('ui-page-theme-a').addClass('ui-page-theme-b');
});
or even better: http://jsfiddle.net/Gajotres/ML2F6/
$(document).on('pagebeforecreate', '#index',function (e, ui) {
$(this).page({theme:'b'});
});
You can simply do it through .page({ theme : "a, b, c" }) widget. It will change the whole page's theme.
$(document).on("pagecreate", function () {
$(".selector").on("click", function () {
$.mobile.pageContainer.pagecontainer("getActivePage").page({
theme: "b"
});
});
});
Demo

CKEditor - move skins folder somewhere else

I'm using CKEditor for the first time and trying to do something that I thought would be very simple to do but so far I've had no success.
Essentially I want to place the editor.js, config.js and styles.js in a scripts folder but want the "Skins" folder that contains the css and images to appear within a separate "Styles" folder.
The application consists of a simple view that displays the editor on load.
The code to display the editor is a follows:
angular.element(document).ready(function () {
CKEDITOR.config.contentsCss = '/Styles/CKEditor/';
CKEDITOR.replace('editor');
});
The HTML within my view is as follows:
#section scripts
{
<script src="~/Scripts/ckeditor.js" type="text/javascript"></script>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/Main.js" type="text/javascript"></script>
}
<h2>Index</h2>
<textarea id="editor" name="editor"></textarea>
This is an MVC application and the scripts are rendered at the end of the body within the layout view.
The editor will not display in any browser. As I understand it setting the contentsCss property should do the trick.
If I place the skins beneath my script folder it works fine. I can see in the generated source that it is adding a link to the header pointing to /Scripts/Skins/moono..., but I want it to add a reference to /Styles/Skins/moono...
Is what I am trying to do feasable and if so what am I missing here? I was expecting this to be simple.
As a work around I could just add some routing rules that redirects the relevant request to a different location, but I'd rather get to the bottom of the issue before I do this.
Further information:
My application is an ASP.net 4.5/MVC 4 app.
I'm referencing angular because I'll be using that once I've sorted this issue. I have tried removing all references to angular but the problem still persists.
I've tried setting the contentsCss property in the following ways:
Directly using CKEDITOR.config.contentsCss
Within the config.js file. The sample assigns an anonymous function to CKEDITOR.editorConfig and in there you can manipulate congif entries.
Passing a config parameter when calling the "replace" method on the CKEditor object.
I've tried manipulating the contentsCss property both before and after the call to replace.
I'm using the latest version of CKEditor (4.2)
Thanks to #Richard Deeming, I've found the answer.
I'm using the default moono style, so I needed to set the CKEDITOR.config.skin property as follows:
CKEDITOR.config.skin = 'moono,/Styles/CKEditor/Skins/moono/'
My final code now looks like this:
angular.element(document).ready(function () {
CKEDITOR.config.skin = 'moono,/Styles/CKEditor/Skins/moono/';
CKEDITOR.replace('editor');
});
You have to set the url to the actual folder containing the skin itself (I thought CKEditor might append skins/mooono itself but it doesn't).
I also found that you must include the final '/' from the URL.
Looking at the documentation, you need to specify the path as part of the skin name:
CKEDITOR.skinName = 'CKeditor,/Styles/CKeditor/';

Should the javascript_include_tag always load last?

Railscast#369 explains how moving the javascript_include tag to the bottom of application.html.erb can shorten loading time, as it allows the page to load at the same time as the javascript.
From the simple example given, it seems like the javascript tag should ALWAYS be at the bottom of the page. However, the fact that the Rails default has it at the top implies (to me at least), that this may not always be true.
When would someone NOT move the javascript tag to the bottom of application.html.erb?
If you call any javascript prior to it loading then you may run into issues. As an example in a view (blah.html.erb) file you might have:
<script>
jquery('#element_id').append("<p>Error Message</p>");
</script>
Which would look for jQuery being loaded by the include tag. Not a good practice but sometimes occurs.
Also, you may use a js view file (blah.js.erb) which would look for jQuery before it is loaded as well.

How does RequireJS work with multiple pages and partial views?

I'm looking into RequireJS but I'm uncertain about some things.
I understand how I can load all my dependencies with main.js.
But do I need to add any logic to work with those dependencies in main.js?
To me, main.js seems like a document.ready state and you enter logic there when the document has loaded, right?
And for other pages and partial views, do I need to create multiple main.js or can I just reference loaded functions in dependencies from the views in a <script> for example?
Update -
I've added an example of using RequireJS with modular HTML components. Build tool example included - https://github.com/simonsmith/modular-html-requirejs
I have also written a blog article about this - http://simonsmith.io/modular-html-components-with-requirejs/
The approach of just using main.js for everything is probably more suited to a single page application.
The way I've handled this situation is to only include common site-wide JS in the main.js file:
On every page:
<script src="require.js" data-main="main"></script>
main.js
require.config({
// config options
});
require(['jquery', 'common/ajaxLoader', 'common/someOtherModule'], function($, ajax, otherModule) {
// Modules that do stuff on every page are instantiated here
});
page1.html
<script>
require(['scripts/page1']);
</script>
page1.js
require(['jquery', 'page1Module'], function($, module){
// page1 specific stuff here
});
The above example is just one of a couple of ways to handle it. Note the difference between loading a plain JavaScript file and a module.
A rule of thumb I follow is to keep all reusable modules (or Classes if it makes it easier to conceptualise) inside a define with their own dependencies etc and then use require to grab those modules, use their methods or interact with them in some way.
Using this pattern will almost certainly require use of the domReady module that is a separate plugin for RequireJS. Use this instead of a ready function in jQuery for example, as it allows modules to begin downloading before the DOM is ready which reduces the wait for your code to execute.
Edit You may wish to see another example of multi-page application in the RequireJS repo
I have recently gone through the exercise of setting up RequrieJS with automatic build optimization in an ASP.NET MVC application. There are a lot of helpful blog articles such as Simon's that are a great reference. From an ASP.NET perspective one of the most useful I found in terms of configuring the RequireJS optimizer for multi-page ASP.NET applications was Making RequireJS play nice with ASP.NET MVC.
Using the great information already out there I have put up my own ASP.NET MVC RequireJS example on GitHub. Much of what is included is similar to examples already out there, however to address the issue of partial views, and multi-page require dependencies I have taken a slightly different approach.
_Layout.cshtml
The most notable difference from existing examples is the creation of a custom RequireViewPage that exposes methods to pass configuration data to RequrieJS as well as reference page specific require dependencies.
So your _Layout.cshtml will look much like what you'd expect with:
<head>
...
#RenderModuleConfig()
<script type="text/javascript" src="#Url.Script("vendor/require.js")" data-main="main"></script>
</head>
<body>
...
Views & Partials
To wire up views (and in my case knockout view models), an additional script fragment has been added to the bottom of _Layout.cshtml as follows
...
#RenderSection("scripts", required: false)
<script type="text/javascript">require(['main'], function () { require(['lib/knockout/knockout.require']); });</script>
</body>
This will ensure that for any view dependency, the main module has been loaded (assuming dependencies for main have being defined in main.js and then allows for view specific dependencies to be wired up via data attributes.
<div data-require="#MainModule"> ... </div>
<div data-require="#Module("address")"> ... </div>
<div data-require="view\home\index\model"> ... </div>
For a full explaination of the design and choices, see the README on GitHub

How do I use CSS to style my form components?

How does Vaadin use CSS that was written purely for HTML elements (e.g. styling and layout of body, h1, etc elements) and use that exact CSS style in Vaadin?
Does one need to make changes on the CSS to map to corresponding Vaadin elements, or can one use that CSS as is?
You can use the CSS as is, but you'll (naturally) have to tell Vaadin which CSS classes to use by calling
myComponent.setStyleName("myStyleClass");
or
myComponent.addStyleName("myStyleClass");
The difference between the two is that setStyleName replaces all existing styles with the provided one and addStyleName doesn't replace anything but adds the provided style for the component.
You can also modify your CSS to override default Vaadin styles, for example
.v-panel .v-panel-content {
background: yellow;
}
would change every Panel's background color to yellow.
I recommend that you create a new theme which is based on an existing Vaadin theme. Here's how to:
Create a directory in the VAADIN/themes/ directory (eg. VAADIN/themes/myTheme).
Create styles.css in your theme directory.
Add #import "../runo/styles.css"; to the beginning of your styles.css (you can replace runo by any other existing theme).
Call setTheme(myTheme); in your Vaadin application class.
If you want to apply application-wide styles, override the Vaadin component CSS definitions in your styles.css. If you don't know the names of the CSS classes, you can use firebug and check the HTML elements' classes.
If you want to create a component-specific style, define it in styles.css and call setStyleName or addStyleName methods.
See the CSS entry in the Book of Vaadin here.
As far as I can tell from looking at the demos, Vaadin just generates HTML, so yes.
Does one need to make changes on the CSS to map to corresponding Vaadin elements, or can one use that CSS as is?
You can use your own CSS styles (just as it is) and it can use for either individual components (as said by "miq*" earlier) or entire page. `
Here is a link for more info:
https://vaadin.com/book/-/page/themes.css.html

Resources