http://demos.dojotoolkit.org/demos/themePreviewer/demo.html
In this theme previewer, no matter how I change theme, nothing happens.
Besides, in any samples of the reference guide, when I try to run them, they appear without styles at all, as if the css is not present.
I tried other browsers, all the same.
Although it works well on my project, I wonder what's wrong.
I can't imagine that it would ever work. I looked at the source code and it doesn't look like it's even attempting to change the CSS location or the classname on the body (both are required to change the theme).
The only thing that seems to happen is that the ?theme= query parameter is only used to define which themes should be displayed as link. But even that's going wrong. They define the themes like this:
var availableThemes = [
{ theme: "claro", author: "Dojo", baseUri: "../themes/" },
{ theme: "tundra", author: "Dojo", baseUri: "../themes/" },
{ theme: "soria", author: "nikolai", baseUri: "../themes/" },
{ theme: "nihilo", author: "nikolai", baseUri: "../themes/" }
];
Then they load the current theme like this:
var curTheme = location.search.replace(/.*theme=([a-z]+).*/, "$1") || "claro";
And then they attempt to load the correct menu options:
var tmpString = '';
array.forEach(availableThemes, function(theme){
if(theme != curTheme){
tmpString +=
'<a href="?theme=' + theme.theme + '">' + theme.theme + '</' + 'a> (' +
'<a href="?theme=' + theme.theme + '&dir=rtl">RTL</' + 'a> ' +
'<a href="?theme=' + theme.theme + '&a11y=true">high-contrast</' + 'a> ' +
'<a href="?theme=' + theme.theme + '&dir=rtl&a11y=true">RTL+high-contrast</' + 'a> )' +
' - by: ' + theme.author + ' <br>';
}
});
But as you can see they're comparing objects to strings (theme != curTheme), which will never work. So, the code seems to be quite errorneous, so I think you can't rely on it. I suggest opening a ticket to report this issue.
If you're interested in how things look like in the other theme, you can open your DevTools and change the CSS file (../../dijit/themes/claro/claro.css should be replaced) and you should change the classname on the <body> tag.
Or you could simply execute the following code in your browser's console:
(function() {
var curTheme = location.search.replace(/.*theme=([a-z]+).*/, "$1") || "claro",
newStyle = document.createElement("link"),
styleSheets = document.styleSheets;
newStyle.setAttribute("rel", "stylesheet");
newStyle.setAttribute("type", "text/css");
for (var idx = 0; idx < styleSheets.length; idx++) {
if (styleSheets[idx].href.indexOf("claro.css") >= 0) {
newStyle.setAttribute("href", styleSheets[idx].href.replace(/claro/g, curTheme));
}
}
document.getElementsByTagName("head")[0].appendChild(newStyle);
document.body.className = curTheme;
}());
Look at the Dijit theme tester instead, which lives in the Dijit package under the themes folder.
You'll probably think it looks nearly identical. It sort of is - the themePreviewer under the demos folder was sort of half-copied from it at some point, but has unfortunately never fully worked, AFAIK.
Related
I have spent long, too long, trying to make all of the directory components work. They took something that could have been super simple and made it complex and difficult.
I finally buckled and tried to copy a javascript function into my project and it worked with a simple method. The method, like all others need to be initiated by some other component. But do that in any way you want it.
All I'll leave here is the code. And the hope that somebody else will find this and use less time than I did.
void copyText(String text){
Page page = UI.getCurrent().getPage();
page.executeJavaScript(
"var el = document.createElement('textarea');" +
"el.value = $0;" +
"el.setAttribute('readonly', '');" +
"el.style = {" +
" position: 'absolute'," +
" left: '-9999px'" +
"};" +
"document.body.appendChild(el);" +
"el.select();" +
"document.execCommand('copy');" +
"document.body.removeChild(el);",
text);
}
void copyText(String text){
Page page = UI.getCurrent().getPage();
page.executeJavaScript(
"var el = document.createElement('textarea');" +
"el.value = $0;" +
"el.setAttribute('readonly', '');" +
"el.style = {" +
" position: 'absolute'," +
" left: '-9999px'" +
"};" +
"document.body.appendChild(el);" +
"el.select();" +
"document.execCommand('copy');" +
"document.body.removeChild(el);",
text);
}
Just to further explain the code. We need to initialize the page and then execute plain javascript-code. In this code, I pass the String text as a parameter and the utilize it in the code as "$0".
The code creates a textarea, which most of the addons in the directory also does. It then sets the text-string, it hide it from the ui with some styling. Then the textarea gets added to our file, because you are only allowed to copy a value that is visible. Then the text is selected, copied, and lastly the textarea is removed. Fast and clean.
You can also add the following line:
el.setSelectionRange(0, 99999);
Add it after the el.select(); line. According to W3, it should work better on phones with this line, but I have not tested it.
I want to use EggImageDropdown, but I have problems with the script.
I embedded it in my testing site and there it works:
http://herzschloss.de/hs/test.php at "Mein Wunschbild".
Now I want to use the same script with the same linked in js-code here:
http://herzschloss.de/Liebesschloss-bestellen at "Mein Wunschbild"
But I get an error.
TypeError: jQuery(...).val(...).EggImageDropdown is not a function
This is the live generated script that didn't work:
function onclick(event) {
var t = jQuery('select[id=dropdown_demo]').val('herz.png').EggImageDropdown('close').EggImageDropdown('update',{src:'hs-motive/herz.png'});t.trigger('change');
}
This is the code:
jQuery('option',element).each(function(i,el){
dropdown.append('<img style="width:100%" onclick="var t=jQuery(\'select[id=' + selectName + ']\').val(\''+ $(el).val() + '\').EggImageDropdown(\'close\').EggImageDropdown(\'update\',{src:\''+ $(el).text() + '\'});t.trigger(\'change\');" src="' + $(el).text() + '"/>');
});
It would be great if you help me!
It's very difficult to embed that much code into an onclick attribute. Better to not do it.
To correct it, create the function directly in the loop instead of creating an attribute.
jQuery('option',element).each(function(i,el){
var img = $('<img>', {style: "width:100%;", src: $(el).text()});
img.click(function() {
var t=jQuery('select[id=' + selectName + ']');
t.val($(el).val()).EggImageDropdown('close')
.EggImageDropdown('update', {src:$(el).text()});
t.trigger('change');
});
dropdown.append(img);
});
Furthermore, looking at your linked site, it appears that the EggImageDropdown function doesn't exist, which means you're not successfully loading the plugin.
I am trying to use video.js which is awesome, and it uses a custom icon font for the interface.
However I need a few more icons, we already use font-awesome on our site, so thought it would be great if we could just use those icons, and since the video.js already uses a custom icon font I thought it should be easy.
So, I added a custom button:
vjs.QuickClip = vjs.Button.extend({
/** #constructor */
init: function (player, options) {
vjs.Button.call(this, player, options);
}
});
vjs.QuickClip.prototype.buttonText = 'Quick Clip';
vjs.QuickClip.prototype.buildCSSClass = function () {
return 'vjs-quickclip-control ' + vjs.Button.prototype.buildCSSClass.call(this);
};
vjs.QuickClip.prototype.onClick = function () {
var offset = 10;
var time = this.player_.currentTime();
var clipStart = time < 10 ? 0 : time - 10;
var clipEnd = time + offset > this.player_.duration() ? this.player_.duration() : time + offset;
console.log('Clipped at ' + time + ' so from ' + clipStart + ' to ' + clipEnd);
};
and tried replacing vjs-quickclip-control with icon icon-crop which partially works.
The little highlighted button is the output.
So, this obviously didn't work, so now I am wondering, how can I do this?
I tried to create a JS fiddle but it doesn't seem to load properly...
Ah, got it,
for my new links I use
.vjs-default-skin .vjs-control.vjs-quickclip-control:before {
font-family: FontAwesome;
content:"\f125";
}
I have the following code within an external javascript file.
jQuery(function ($) {
//////////////////////UPCOMING EVENTS JSON SERVER START///////////////////////////
var eventList = $("#eventList"); //cache the element
$.getJSON("/JsonControl/Events.json", function (jsonObj) {
val = "";
for (var i = 0; i < jsonObj.events.length; ++i) {
val += "<p>" + jsonObj.events[i].dateMonth + "/" + jsonObj.events[i].dateNumber +
"/" + jsonObj.events[i].dateYear + " - <span id='EL" + i + "' class='link' " +
"onclick=plotEvent(" + i +")>" + jsonObj.events[i].title + "</span></p>";
}
eventList.html(val);
});
//////////////////////UPCOMING EVENTS JSON SERVER END/////////////////////////////
});
function plotEvent(index)
{
$.ajax({
url: "/JsonControl/Events.json",
dataType: 'json',
async: false,
success: function (jsonObj)
{
var eventBox = window.frameElement;
alert("This alert fires in all browsers, including IE9")
eventBox.onload = function ()
{
alert("This alert doesn't fire in IE9.")
window.frameElement.onload = null; // unset it so it only fires once
eventBox = eventBox.contentDocument || eventBox.contentWindow.document;
eventBox.getElementById("title").innerHTML = (jsonObj.events[index].title);
eventBox.getElementById("content").innerHTML = (jsonObj.events[index].explanation);
eventBox.getElementById("dateHolder").innerHTML = (jsonObj.events[index].dateMonth + "-" + jsonObj.events[index].dateNumber + "-" + jsonObj.events[index].dateYear);
};
eventBox.src="/Event htms/Event.htm";
}
});
}
The page that loads this script is in the iframe itself. A very similar function called in a different external js file, from the main page outside of the iframe (for a different but similar purpose) works in all browsers just fine. The only difference is that with this code I have to target the onload of the iframe from within the iframe, instead of just grabbing the iframe by id. I then attempt to change, the onload of said iframe, for use with the next internal iframe page (which is why I need to preserve the json array index [i] when dynamically writing the first iframe page's innerHTML.
Sorry if that was a bit wordy, and/or confusing, but suffice it to say that with using the above-pasted code, I have no problems... except with IE (tried in IE9). I have tried dozens of examples and supposed solutions, but nothing has worked. Using IE9.
Here's what I mean when I say 'it doesn't work in IE9':
This part of the code within plotEvent() doesn't fire:
eventBox.onload = function ()
{
alert("This alert doesn't fire in IE9.")
window.frameElement.onload = null; // unset it so it only fires once
eventBox = eventBox.contentDocument || eventBox.contentWindow.document;
eventBox.getElementById("title").innerHTML = (jsonObj.events[index].title);
eventBox.getElementById("content").innerHTML = (jsonObj.events[index].explanation);
eventBox.getElementById("dateHolder").innerHTML = (jsonObj.events[index].dateMonth + "-" + jsonObj.events[index].dateNumber + "-" + jsonObj.events[index].dateYear);
};
Is there any solution to this problem, or is this sort of thing why iframes aren't used more often (that is, that IE doesn't fully support them)?
Try eventBox.contentWindow.onload or maybe $(eventBox).load(function)
I am trying to integrate a sticky headers technique like the one shown here... Persistent Headers.
I have tried to integrate it into my code and for the most part have been successful, however it isn't behaving correctly and I REALLY can't figure it out.
I'll try to explain in a nutshell what the page it is being used on does. I have a database with a table of students and another table of assessments. This page loops through a JSON object (recieved from the database via a PHP script) and then for each student in that first object fetches another JSON with their assessments. This all works fine. It does however create a fairly long page. Visually it looks like this...
Code rendered in Chrome
The code I have written based on that tutorial I posted above is supposed to clone headers specified by a class and then hide or show them based on some logic involving scrollTop the position of the element and the length of the element. This having the effect of the header sticking to the top of the page while the container it belongs to is still visible.
The problem is something is going wrong and although all the headers are shown in sequence they are way too early, they seem to hang about for different lengths of time, and these lengths do seem to correlate to how long the container it belongs to is.
So my code...
Firstly the function used to update the headers...
containerArray = new Array;
positionArray = new Array;
floatingHeaderArray = new Array;
function updateTableHeaders() {
$(".studentContainer").each(function(i) {
containerArray[i] = $(this);
var position = containerArray[i].position();
positionArray[i] = position.top;
var scrollTop = $("#main").scrollTop();
floatingHeaderArray[i] = $(".floatingHeader", this);
if ((scrollTop > positionArray[i]) && (scrollTop < positionArray[i] + containerArray[i].outerHeight(true))) {
floatingHeaderArray[i].css({
"visibility": "visible"
});
} else {
floatingHeaderArray[i].css({
"visibility": "hidden"
});
};
});
}
Now the code that generates the containers, headers and tabs.
$("#mainContent").fadeIn(0);
loadMessage = "Loading data for " + event.target.id;
$.getJSON('php/oneFullClass.php?techClass=' + event.target.id, function(data) {
$('#mainTitle').fadeOut(0);
$('#action').html('You are ' + actionIntent + 'ing ' + event.target.id);
$('#action').fadeIn(300);
$('#mainTitle').fadeIn(300);
$('#mainContent').append('<div id="scrollTopDisplay"></div>')
dynamicPositioning();
$.each(data, function(key, val) {
var thisPosition = positionArray[0]
$('#mainContent').append(
'<div class="studentContainer studentView" id="' + val.idStudent + '">' +
'<div class="studentName">' + val.name + ' ' + val.surname + ' - (' + val.form.substr(0, 1) + '/' + val.form.substr(1, 2) + ')</div>' +
'<div class="floatingHeader">' + val.name + ' ' + val.surname + ' - (' + val.form.substr(0, 1) + '/' + val.form.substr(1, 2) + ')</div>' +
'<div class="studentTarget"> Target: <strong>' + val.target + '</strong></div>' +
'</div>');
$(".studentContainer").hide().each(function(i) {
//$(this).slideDown(0);
$(this).delay(i * 50).slideDown(300).fadeIn(500);
})
//Get previous assessments for this student and build tabs
buildTabs('php/allPreviousAssess.php?sid=' + val.idStudent, val.idStudent);
});
});
$('#mainContent').append('<div id="expandAll" onClick="expandAll()">Expand</div>');
$('#mainContent').append('<div id="collapseAll" onClick="collapseAll()">Collapse</div>');
dynamicPositioning();
$('#expandAll').delay(300).fadeIn(300);
$('#collapseAll').delay(300).fadeIn(300);
$("#main").scroll(updateTableHeaders);
I think that's all the info you'll need but I'll post any other code that may be referenced in this code if you think it'll help figure it out.
I have a suspicion that the problem is something to do with the animated slide in effect I am using on the 'assessment cards' messing with the position values, or possible position()'s inability to get positions of hidden elements. However, as I call updateTableHeaders() with every scroll event, this shouldn't be an issue as all animation is over by the time you are given access to the layout (there is a modal shade effect that only dissapears once all AJAX requests are complete.
I hope someone can help, this one is making me unhappy! :(
Balloon, a library I wrote for easily making your headers stick, is pretty hassle-free. You simply make a Balloon object instance, specifying if you want your sticky headers to be stacked or replaced, and then inflate the headers by passing in the strings of their ids. Give it a try and let me know if it helped you:
https://github.com/vhiremath4/Balloon
If you find any issues with it, file a bug report on the repository, but I feel like it should do its job in your case.