When using jQuery Mobile .js along with jQuery Mobile .css, what is the best way to customize the default styling such as a link button?
Using jQM, a simple link can be turned into a button by using the following code:
Link button
data-role="button" allows jQM to add classes to the link so it can be styled into mobile button touch abled like so:
<a href="index.html" data-role="button" data-corners="true" data-shadow="true"
data-iconshadow="true" data-wrapperels="span" data-theme="c" class="ui-btn
ui-shadow ui-btn-corner-all ui-btn-up-c"><span class="ui-btn-inner
ui-btn-corner-all"><span class="ui-btn-text">Link button</span></span></a>
Is it OK to actually edit the jQM css file for example the ui-btn-up-c class? Or is it better to override the styles somehow, perhaps in an external stylesheet?
I have a couple of concerns. I am wondering if it's possible to break some of the functionality by directly editing jQM.css as jQM seems to use the stylesheet heavily.
Also will it be a problem on updating? Do jQM release a new stylesheet when a new version comes out which would override my edits to the main jQM stylesheet?
Basically what I am asking is how do I edit the jQuery Mobile built in theme?
Thanks and look forward to your answers :)
Intro
If you want to change classic jQuery Mobile CSS everything depends on what do you want to do.
Theme roller
Classic way would be to create a completely new set of theme's or add them to existing ones. It is done through jQuery Mobile theme roller. When you open it it will automatically create 3 themes you can then modify as you wish. Or you can Import your current theme CSS and add several more themes (this is probably best solution if you want to change complete look).
Custom CSS changes
This solution requires a little bit of finesse. First if possible NEVER change original CSS unless you are 100% sure what you are doing. For example if you change default button classes it will also affect other widgets that use button classes and there are a lot of them.
Correct way would be to change single/multiple elements with custom CSS file. This way original CSS files is intact and new one can be changed / removed at any time.
To do this you will need to use Chrome Webmaster tools or additional plugin called Firebug (for Chrome and FireFox). There are several more solutions but this two are most commonly used.
Problem to think about
Not all is well in this solution. For example, classic a tag button can be easily modified cause that same a tag will stay as a parent of a future styled jQuery Button. But, if your button is created from input tag, like this:
<input type="text" value="Some value" id="change-me"/>
you cant use #change-me id to correct its CSS. Mainly because this input is not a parent tag for a future button, it will be a inner part of a button when jQuery Mobile styles it. It will look like this:
<div class="ui-input-text ui-shadow-inset ui-corner-all ui-btn-shadow ui-body-c">
<input type="text" id="change-me" value="Some value" class="ui-input-text ui-body-c"/>
</div>
To fix this wrap that input with another div element. Move id from input to div element and then use it to change inner CSS styles.
How to correctly override CSS styles
This is one of a most common questions in this StackOverflow group. When changing predefined CSS rules you must use !important keyword. Changes will usually not work without it. For example if you want to change input button style background (from a previous example, wrapped in a div) you would do it like this:
#change-me .ui-input-text {
background-color: red !important;
}
If nothing else works change original CSS file(s)
jQuery Mobile can have 1 or 2 CSS files. When using one file both theme and structure is included, or they can be separated into two files. This is useful if you want to change CSS directly. Theme CSS can be easily imported and exported into theme roller without affecting structure CSS file.
One last thing, some things can only be changed by modifying original structure CSS file. For example jQuery Mobile uses a horrible blue glow effect to show when some element has been pressed. It can be removed only directly from structure CSS file.
The solution lies in CSS specificity within your own additional CSS file. All you need to do to override any formatting in JQM is to first apply an id to the element you wish to override JQM formatting with your own CSS.
Next, in your own CSS, specify that the class be applied to the id of the container.
As an example, I'll remove the JQM border from an image link below.
#img_button_1 .ui-btn-inner {border: none !important;}
Where #img_button_1 is the id of the HTML anchor element.
<a id="img_button_1" data-role="button" data-theme="none" data-corners="false" data-shadow="false" data-inline="true"
href="http://www.google.com" target="_blank"><img src="http://www.google.com/images/srpr/logo1w.png" alt="Google" />
</a>
It's as simple as that.
One more important thing, and that is that load order of the external CSS files is significant, and you will want to load your own CSS after JQM CSS.
I have forked a working example at jsFiddle below.
http://jsfiddle.net/Z8Xnx/14/
The biggest benefit with this approach, is you do not have to alter the JQM CSS at all, and can leave it alone. This becomes important if your want to import your JQM back into the ThemeRoller tool at a later date. If you modify the actual JQM CSS by hand, you may have an issue successfully importing your JQM back into ThemeRoller again.
I have successfully used this approach to resolve every JQM CSS conflict I have run across since figuring out this specicivity requirement issue.
Hope this helps everyone with an easy solution to their JQM style conundrums.
** UPDATE **
It has been noted to me that this method does not work with the latest version of JQM (1.3.0b1), and that is not correct. I have investigated and found this to be a problem with the implementation of this version of JQM at jsFiddle. To prove this, I have put up an example page on my own space with the exact same code as that shown in the jsFiddle example. This means as of my writting, you really can't trust anything at jsFiddle using the lastest version of JQM from the options. Just a heads up, and you can find the working implementation at...
jQuery Mobile CSS Override Example
If you are looking to simply change the styling then you can use the jQuery Mobile themeroller.
http://jquerymobile.com/themeroller/index.php
Otherwise, I would suggest using another stylesheet rather than directly editing the jQuery mobile stylesheet.
If you are looking to reduce the number of files that you are serving to your visitors then I would compress both stylesheets and then just insert your styles below their styles as a production copy. That way, you can keep them compressed and combined for production, but you could keep them separate for easy upgrading later and for development ease of use.
Related
grails v 3.3.9, fields plugin
fighting with fields plgin and theres a problem when rendering domain objects and using bootstrap
i've got a sample here from a simple standalone page to show the problem
<p>f:display category </p>
<f:display bean="maintenanceAgreement" >
</f:display>
<hr />
<p>f:field category</p>
<f:field bean="${this.pageScope.maintenanceAgreement}" property="category">
<g:render template="/_fields/map/displayWidget" ></g:render>
</f:field>
<hr />
in essenence i have added a template in "/_fields/map/displayWidget" that renders a drop right table on a button
when you render a map field directly from your Domain object the sample table opens and you get all of the table
however when you
you can see the differences between using f.display (has clipping problem), f.field ( which seems to work) and f.all that ignores my _fields/map/_displayWidget.gsp
I dont want to have not use the fields plugin but its not working with bootstrap templating
has any one come up with a fix for this problem?
the project demo page is here
github standalone page to show rendering problem
the attached shows the output as you try each and select category property
well goldarn it another 2 days down the pan - but i have it !
I thought at first it was something to do with fields plugin processing. so i hacked a clone of plugin project locally and added some bits so i could watch it/debug step through it
in doing so i noted that my dummy web domain class page i'd cut across to the plugin didnt have the clipping problem. but the styles were not the same so i copied main.css and grails.css from ordinary project back into the plugin, then re rendered in the browser - and the clipping happened again.
so its in the css!. some very careful watching of browser and looking at the browser 'inspect' indicated that the clipping seemed to be enabled very early on in the journey.
so in my dummy page i just used
I then spent a day wandering round the various bits of fields plugin as its not that well explained anywhere.
if you look at the plugins taglib display method, by default that triggers the /templates/fields/_list.gsp. naming is a little odd but its the gsp that renders the domains persistent attributes as an ordered list - the plugins default _list.gsp looks like this
<ol class="property-list ${domainClass.decapitalizedName}">
<g:each in="${domainProperties}" var="p">
<li class="fieldcontain">
<span id="${p.name}-label" class="property-label"><g:message code="${domainClass.decapitalizedName}.${p.name}.label" default="${p.defaultLabel}" /></span>
<div class="property-value" aria-labelledby="${p.name}-label">${body(p)}</div>
</li>
</g:each>
</ol>
so after much exploration coming up through templates, from the bottom I ended up right at the top with the '
so nearly there now. back into main.css that i'd copied in. if you edit that, down around line 215 you get this style. If you comment out the overflow property - its all fixed !
.property-list .fieldcontain {
list-style: none;
/*overflow: hidden; */
zoom: 1;
}
I tried auto, scroll, and visible but that seems to much about with too much of the page so best to just comment it out.
once you do that - the rest of the rendering of your forms starts to work !! blimey one line of css for all that pain. Attached is the page using
Lastly through out all this, id ended up digging through /tracing fields plugin. What a nest that is. Not really finished here, but basically
with no body just renders a label and no content. So you either need to provide provide a body tag, say to get the value field displayed.
as
if no widget template has been defined then the renderDefaultDisplay is called which again has very limited options for controlling the rendering by falling through a 'switch (prop.type)' and basically calls either g.format (bool), g.formatDate (but no LocalDateTime/LocalDate Support) or g.fieldValue, non of which are bootstrap enabled.
if you call
these two diagrams are not beautiful but just high level pseudo code walk through for what the core tags are trying to do. One day i'll try and pretty that up but it might help you if you get stuck
I'll raise a bug for the main.css clipping directly to the grails team and see what happens, but you can comment the line out yourself if you fall foul of it.
[Stackoverflow disallows the word help in the title. Hence the h3lp]
We are in the proces of moving our code from Orbeon 3.9 to Orbeon 4.x. One of the many things that changed is the behavior for display of xforms:alert and xforms:help. Example code:
<xforms:input ref="#code">
<xforms:alert ref="$resources/required-field"/>
<xforms:help ref="$helptext"/>
</xforms:input>
In Orbeon 3.9 the alert is displayed as a red img with a white exclamation mark that has the text as tooltip, only if the binding fails. The help is displayed as a blue-ish image with a question that activated a tiny pseudo window containing the (potentially large) help text.
In Orbeon 4.7 the alert text is displayed as-is, no image and no condition based on binding. This interferes with a carefully designed interface as it takes up a lot more space. The help text is not displayed at all because .xforms-help has display: none;. Overriding that doesn't work because the text would then just be displayed inline.
I could not find documentation for these changes. Does anyone know the rationale and how to make "alert" and "help" useful yet again?
There are two changes with Orbeon Forms 4.x which might be relevant to this:
The HTML layout of elements has changed a bit. This means existing CSS might have to be adapted. You can check this by comparing the HTML produced by 3.9 vs. 4.x for a given page. With 4.x, all form elements, for example, are wrapped within a <span> or <div> element.
Form Runner uses Twitter Bootstrap as a CSS library. But the Bootstrap CSS files are also included for non-Form Runner pages.
This said, "red icon" alerts should still work, see for example the good old Espresso Order or Bookcast demos.
If you see alerts inline and unconditionally, it means that somehow the proper CSS doesn't apply, either because of the HTML layout change mentioned above, or because some CSS files are missing.
Look at this post : http://blog.orbeon.com/2014/01/improving-how-we-show-help-messages.html
and this : http://discuss.orbeon.com/how-to-use-the-quot-new-quot-xforms-help-in-4-5-td4658348.html
julien
I want to increase the size of the Calendar view because the default size is too small for my web application. I've tried to add a cssClass to the datetimepicker tag but it doesn't work, even if I change the width or height the only thing it changes is the field, not the calendar itself.
I'll put an image so you can understand better the problem that I have:
The thing is that the text from the field is correctly viewed, but when I click the calendar button, it shows that tiny view and it's extremelly difficult to pick one date.
The code for the datetimepicker is this:
<sx:datetimepicker name="start_date" displayFormat="dd-MMM-yyyy" value="%{'today'}" />
Any guess?
Ok, It's finally solved:
First I tried to find the file named datefilepicker.ftl inside the struts2-core.jar but I didn't find anything similar.
So after a few hours trying to find which was the correct template of datetimepicker without any luck, I tried to solve my problem using JQuery because when I was searching for the answer I found out a datepicker tutorial using this library.
There's a plugin called Struts2-JQuery that provides you with ajax functionality and therefore with multiple customizations in different widgets.
It's quite easy to install, I just had to download the correct .jar which for me it was Version 3.5.1 ( jQuery 1.8.3, jQuery UI 1.9.2 ). Once I'd downloaded the file, I just had to paste it in the lib folder inside my project. After doing that, I added this line at the beginning of the .jsp file:
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
With these steps I had jquery functionality inside my .jsp file, so the only thing left to do is to add the datepicker widget:
First I chose the jquerytheme I wanted for my widget, just like this:
<head>
<sj:head jquerytheme="flick"/>
...
</head>
And then, I added my datepicker widget:
<sj:datepicker name="start_date" displayFormat="dd-MM-yy" value="today"/>
And that's it.
If you want to resize the datepicker calendar see the answer of this post:
How to resize the jQuery DatePicker control
<sx:datetimepicker name="start_date" displayFormat="dd-MMM-yyyy" value="%{'today'}" />
It is a dojo tag, so you should be changing the template file corresponding to this tag
Freemarker changes
check for something like datetimepicker.ftl in your workspace. That would be the file rendering your calendar. Any presentation related changes will be done in that file only.
debug using firebug
Another approach can be using firebug in Mozilla firefox and manually try to change the html rendered by the tag. There might lie some CSS solution to your problem
I am using Django and the django-dynamic-formset plugin to generate a JQuery Mobile (JQM) site. I have nested forms that allow the user to click a "Add" link to another line to the form. This works great without JQM, but when JQM is used to style the form widgets the radio button labels do not trigger the correct radio button.
I have put up a static example of the behaviour, based on the generated HTML. Click the "Add" link, then try choosing a severity for the added item. The "for" attributes of the labels appear to update correctly, so I do not know what I'm doing wrong.
The django-dynamic-formset guide provides me with a way to call a JavaScript function after the user clicks the "Add" button, but I do not know if there's a JQM method I should be calling that will fix the issue. When I use JQM's enhanceWithin function it triggers a page load, which submits my form to Django, which I don't want at that point because the form won't validate yet.
Edit: I uploaded a much better example to the same URL.
After enough caffeine and peanut M&M's I have figured it out.
Reason for Failure: The django-dynamic-formset (DDF) plugin duplicates the form you give it. But the form is cloned as-is, which already includes all the JQuery Mobile (JQM) processing. This causes JQM to ignore it and makes the radio buttons misbehave.
The Solution: The DDF plugin allows you to specify what form to clone by its formTemplate parameter. JQM allows you to disable automatic mobile-enhancement of certain elements. Create an un-enhanced version of your form, and pass that to DDF as your formTemplate.
More Details:
I put this coded into my HTML head, before the reference to JQM:
<script>
$(document).bind('mobileinit',function(){
$.mobile.ignoreContentEnabled = true; // required for using the natural forms
});
</script>
And included this style to hide my "natural" form:
<style>
.natural-form { visibility: hidden; display: none; }
</style>
In the Django code I added a <div class='natural-form> and put a dummy version of my form in it (being sure to surround it another <div> with a unique ID for reference later). In my initialization of DDF I give it the unique ID as the parameter to formTemplate.
I was told on another forum I would have to hack DDF and JQM to get this to work. I am impressed at the design of both of these libraries - flexible enough that a newbie to JQuery can stick all the pieces in the right places and get something out of it.
A question similar to this has been posted several time, but I cannot find a solution that works. Hopefully, someone can help!
I am using jQuery Mobile 1.1 and jQuery 1.7.2, so I'm on the most recent stable releases. I want to create a dynamic page header. Using this HTML code, it works fine:
<div data-role="page" id="levela">
<div data-role="header" id="hdr_levela">
<h1>Title</h1>
</div>
</div>
So I then go to dynamically create the title. I change the HTML to this:
<div data-role="page" id="levela">
<div data-role="header" id="hdr_levela">
</div>
</div>
And added the following jQuery code:
// Set the header
var dirHeader = $('#hdr_levela');
dirHeader.append('<h1>' + title+ '</h1>');
The title appears, but is not styled. I have found several posts about this. In the jQuery Mobile Documentation, it says:
"However, if you generate new markup client-side or load in content via Ajax and inject it into a page, you can trigger the create event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page div itself), saving you the task of manually initializing each plugin (listview button, select, etc.).
For example, if a block of HTML markup (say a login form) was loaded in through Ajax, trigger the create event to automatically transform all the widgets it contains (inputs and buttons in this case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page" ).trigger( "create" );
So I tried several things. After the above code, I added the following:
dirHeader.trigger("create");
This had no effect. So I tried to put it on the actual append itself:
dirHeader.append('<h1>' + folderName + '</h1>').trigger("create");
This had no effect. I then tried the process on the parent element (in this case, the id of the parent div is "levela"). So I tried this:
$('#levela').trigger("create");
This also had no effect. At this point, I am completely lost. Every solution involves doing one of the things I have tried and is just not working. I must be missing something incredibly basic but I just can't seem to find it.
Thanks in advance for your help!
You can update the content by calling .page:
See this working Fiddle Example!
// Set the header
var title = 'super hyper BuBu',
$dirHeader = $('#hdr_levela');
$dirHeader.append('<h1>' + title+ '</h1>').page();
I just solved a similar problem -- it appears that jQM headers and footers do not have the "create" method, so as far as I can tell, the css classes and roles need to be added manually.
For reference, I posted an example fix on this (old) question: JQuery Mobile trigger('create') command not working