Below is my entire code from a User control that contains the YUI Uploader. Is there something I'm missing. Right now, when I step through the javascript code in Firebug, it hangs on the first line of the upload() function. I have a breakpoint on the first line of the ashx that handles the file, but it is never called. So, it doesn't get that far. I figure I'm just missing something stupid. I've used this control many times before with no issues. I'm using all the css files and graphics provided by the samples folder in the YUI download.
If I'm not missing anything, is there a more comprehensive way of debuging this issue then through stepping through the javascript with FireBug. I've tried turning the logging for YUI on and off, and never get any logs anywhere. I'm not sure where to go now.
<style type="text/css">
#divFile
{
background-color:White;
border:2px inset Ivory;
height:21px;
margin-left:-2px;
margin-right:9px;
width:125px;
}
</style>
<ajaxToolkit:RoundedCornersExtender runat="server" Corners="All" Radius="6" ID="rceContainer" TargetControlID="pnlMMAdmin" />
<asp:Panel ID="pnlMMAdmin" runat="server"
Width="100%" BackColor="Silver" ForeColor="#ffffff" Font-Bold="true" Font-Size="16px">
<div style="padding: 5px; text-align:center; width: 100%;">
<table style="width: 100% ; border: none; text-align: left;">
<tr>
<td style="width: 460px; vertical-align: top;">
<!-- information panel -->
<ajaxToolkit:RoundedCornersExtender runat="server" Corners="All" Radius="6" ID="RoundedCornersExtender1" TargetControlID="pnlInfo" />
<asp:Panel ID="pnlInfo" runat="server"
Width="100%" BackColor="Silver" ForeColor="#ffffff" Font-Bold="true" Font-Size="16px">
<div id="infoPanel" style="padding: 5px; text-align:left; width: 100%;">
<table>
<tr><td>Chart</td><td>
<table><tr><td><div id="divFile" ></div></td><td><div id="uploaderContainer" style="width:60px; height:25px"></div></td></tr>
<tr><td colspan="2"><div id="progressBar"></div></td></tr></table>
</td></tr>
</table>
</div></asp:Panel>
<script type="text/javascript" language="javascript">
WYSIWYG.attach('<%= txtComment.ClientID %>', full);
var uploader = new YAHOO.widget.Uploader("uploaderContainer", "assets/buttonSkin.jpg");
uploader.addListener('contentReady', handleContentReady);
uploader.addListener('fileSelect', onFileSelect)
uploader.addListener('uploadStart', onUploadStart);
uploader.addListener('uploadProgress', onUploadProgress);
uploader.addListener('uploadCancel', onUploadCancel);
uploader.addListener('uploadComplete', onUploadComplete);
uploader.addListener('uploadCompleteData', onUploadResponse);
uploader.addListener('uploadError', onUploadError);
function handleContentReady() {
// Allows the uploader to send log messages to trace, as well as to YAHOO.log
uploader.setAllowLogging(false);
// Restrict selection to a single file (that's what it is by default,
// just demonstrating how).
uploader.setAllowMultipleFiles(false);
// New set of file filters.
var ff = new Array({ description: "Images", extensions: "*.jpg;*.png;*.gif" });
// Apply new set of file filters to the uploader.
uploader.setFileFilters(ff);
}
var fileID;
function onFileSelect(event) {
for (var item in event.fileList) {
if (YAHOO.lang.hasOwnProperty(event.fileList, item)) {
YAHOO.log(event.fileList[item].id);
fileID = event.fileList[item].id;
}
}
uploader.disable();
var filename = document.getElementById("divFile");
filename.innerHTML = event.fileList[fileID].name;
var progressbar = document.getElementById("progressBar");
progressbar.innerHTML = "Please wait... Starting upload.... ";
upload(fileID);
}
function upload(idFile) {
// file hangs right here. **************************
progressBar.innerHTML = "Upload starting... ";
if (idFile != null) {
uploader.upload(idFile, "AdminFileUploader.ashx", "POST");
fileID = null;
}
}
function handleClearFiles() {
uploader.clearFileList();
uploader.enable();
fileID = null;
var filename = document.getElementById("divFile");
filename.innerHTML = "";
var progressbar = document.getElementById("progressBar");
progressbar.innerHTML = "";
}
function onUploadProgress(event) {
prog = Math.round(300 * (event["bytesLoaded"] / event["bytesTotal"]));
progbar = "<div style=\"background-color: #f00; height: 5px; width: " + prog + "px\"/>";
var progressbar = document.getElementById("progressBar");
progressbar.innerHTML = progbar;
}
function onUploadComplete(event) {
uploader.clearFileList();
uploader.enable();
progbar = "<div style=\"background-color: #f00; height: 5px; width: 300px\"/>";
var progressbar = document.getElementById("progressBar");
progressbar.innerHTML = progbar;
alert('File Uploaded');
}
function onUploadStart(event) {
alert('upload start');
}
function onUploadError(event) {
alert('upload error');
}
function onUploadCancel(event) {
alert('upload cancel');
}
function onUploadResponse(event) {
alert('upload response');
}
</script>
It seems that there is a case mismatch in the name of the progressbar variable: you refer to it as progressbar everywhere else, but as progressBar in the upload() function.
An even bigger problem is that you define the progressbar variable inside the onFileSelect function. Because of that, the variable is limited in scope and should not be accessible anywhere else.
See if moving the definition for progressbar out of there (or freshly grabbing it from the DOM everywhere it's used by using getElementById) and fixing the case mismatch solves your issues.
YUI 2.8 has issues with events and the uploader. It won't work unless you use 2.9 event and uploader. I wasted more time than I want to admit trying to get 2.8 to work. I hope this saves someone that time.
Related
I'm actually using node js and html-pdf lib to generate a pdf on the server which is return as a blob to the client. When I did it on my local machine everything is fine but when I upload it to the server and test it out. The text size increases when in production.
I've created a function that takes an object as a parameter:
async function generatePDF(object) {
let htmlContent = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body,
html {
font-family: arial, sans-serif;
color: rgb(46, 46, 46);
}
</style>
</head>
<body>
<br />
Date: ${object.todayDate}
<div style="margin-top: 60px">
<h3 style="border-top: 1px solid black">Dr. ${object.name} ${object.firstname}</h3>
</div>
</html>
`;
Down below is the code to generate PDF from the HTML file created:
let sideMargin = "1.5cm";
var options = {
format: "A5",
border: {
top: "1.5cm", // default is 0, units: mm, cm, in, px
right: sideMargin,
bottom: "3.0cm",
left: sideMargin,
},
};
console.log(options);
var path = require("path");
var appDir = path.dirname(require.main.filename);
let date = Date.now();
let newPDF = `${appDir}/files/${date}new.pdf`;
let newHTML = `${appDir}/files/${date}new.html`;
htmlData["fileName"] = newHTML;
console.log(`Generating new PDF '${newPDF}`);
await generatePDF(htmlData);
var html = fs.readFileSync(`${newHTML}`, "utf8");
pdf.create(html, options).toFile(`${newPDF}`, function (err, res) {
if (err) return console.log(err);
console.log(res);
r.sendFile(`${newPDF}`, (error) => {
if (!error) {
fs.unlinkSync(`${newPDF}`);
fs.unlinkSync(`${newHTML}`);
}
});
});
The problem is that locally on my machine everything is fine, but online the text size of the PDF is way bigger, and instead of returning one page it's returning back two pages (of course the content I've set here in the HTML is not the result I want, it is just an example).
Hey i've found what was the problem,
there is no solution to this problem yet. The work around is to add
html {
zoom: 0.55;
}
to the CSS file/code
There's actually an open issue for this.
I'm using MathJax in Anki to make notes. When I use "Cloze" note type and put some MathJax in cloze deletion, the lines are suddenly broken, but outside cloze deletion MathJax renders as expected. Here is an example 1.
My front template:
{{cloze:Text}}
<script type="text/x-mathjax-config">
MathJax.Hub.processSectionDelay = 0;
MathJax.Hub.Config({
messageStyle: 'none',
showProcessingMessages: false,
tex2jax: {
inlineMath: [['$', '$']],
displayMath: [['$$', '$$']],
processEscapes: true
},
SVG: {
scale: (!!navigator.userAgent.match(/(mac)|(mobile)/i) ? 100 : 180)
}
});
</script>
<script type="text/javascript">
(function() {
if (window.MathJax != null) {
var card = document.querySelector('.card');
MathJax.Hub.Queue(['Typeset', MathJax.Hub, card]);
return;
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_SVG';
document.body.appendChild(script);
})();
</script>
And styling:
.card {
font-family: calibri;
font-size: 20px;
text-align: center;
color: black;
background-color: lightgray;
}
.cloze {
font-weight: bold;
color: blue;
}
How to fix this problem?
If you are using a WebKit-based browser (e.g., Safari or Chrome), then recent changes in WebKit may be the cause of your issue. The way MathJax checked for the available width for the math now causes unwanted line breaks in WebKit. (See this issue in the MathJax issue tracker.)
This was fixed in version 2.7.5, so you should upgrade to that. You are currently using 2.7.1, so changing
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_SVG';
to
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_SVG';
will do it. Changing it to
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-MML-AM_SVG';
will make sure you have the most current (2.x) version automatically (i.e., even though you are calling from 2.7.5, if there is an update to 2.7.6, you will be switched to that automatically).
Working on a little self project and having some trouble getting text placed on top of my background video.
At present, the code is sitting as follows:
<div class="video_container">
<div class="contentContainer">
<div class="skipButton">
<h1>Skip</h1>
</div>
<video id="tgVideo" autoplay loop>
<source src="videos/bgvidm4v.m4v" preload="none">
</video>
</div>
</div>
I am making the video full screen and keep this way when displaying on different size monitors by using the following JS
$(document).ready(function () {
var vid = $('video');
var vid_w_orig = 1280;
var vid_h_orig = 720;
// re-scale image when window resizes
$(window).resize(function () {
//Get the parent element size
var container_w = vid.parent().width();
var container_h = vid.parent().height();
//Use largest scale factor of horizontal/vertical
var scale_w = container_w / vid_w_orig;
var scale_h = container_h / vid_h_orig;
var scale = scale_w > scale_h ? scale_w : scale_h;
//Scale the video to fit any size screen
vid.width(scale * vid_w_orig);
vid.height(scale * vid_h_orig);
});
//Trigger re-scale of the video on pageload
$(window).trigger('resize');
});
This combination is working flawlessly for me so far. Only issue is getting the video to run on Android/iOS, but I think that's a limitation of the device.
What I am in need of is adding a piece of text for now that a user can click on to bring them away from the video. I am adding the href to the button after I get the text to display on top of the video.
I have found some tutorials online and have tried the below
.video_container .contentContainer {
position: absolute;
width: 100%;
height:100%;
background:#000;
opacity:0.5;
z-index:999;
}
.video_container .contentContainer .skipButton {
width:100%;
text-align:center;
}
.video_container .contentContainer .skipButton h1 {
color:#FFF;
text-transform:uppercase;
}
This is working for the most part, where I can see the text for a split second before it disappears behind the video.
Anyone have any tips for me?
Cheers!
You are setting the whole container to z-index: 999, this element .contentContainer contains also the video element. So I would put z-index only on the text containers alone with non-static position in order z-index to take effect.
.video_container .contentContainer {
position: absolute;
width: 100%;
height:100%;
background:#000;
opacity:0.5;
z-index:999; // not needed
}
.video_container .contentContainer .skipButton {
width:100%;
text-align:center;
position: relative;
z-index: 1000;
}
.video_container .contentContainer .skipButton h1 {
color:#FFF;
text-transform:uppercase;
position: relative;
z-index: 1000;
}
I'm new to Knockout JS and I find this library very powerful, but quite hard to understand sometimes. The documentation is hudge, but it's always (too) small code snippets, so it's difficult to have the big picture, unless your coding style & philosophy paradigm are the same as KO developers.
I come from angular world, and I'm used to have an array where each item is an object with properties (id, name, etc). When I click a button, I "send" this object to a new component that will render it in a form.
I'm sure I'm missing something obvious, but I don't understand how to make things work, even with plugins like ko.mapping and ko.postbox.
Does anyone can help me to find the solution? In the working code above, I've posted my 3 very specific questions in the javascript area.
EDIT: I answered to them, but I don't know if it's a best practice or not.
var
// User class to give to each property the observable capacity
User = function (rawData) {
var self = this,
data = rawData || {};
self.id = ko.observable(data.id);
self.name = ko.observable(data.name);
},
// List component. initially in a separate file
// (small modifs so all can be in the same file for this demo)
cmplist = {
viewModel: function () {
var self = this;
self.users = ko.observableArray([
new User({id: 1, name: 'John'}),
new User({id: 2, name: 'Jack'}),
new User({id: 3, name: 'Smith'})
]);
// #ANSWER 1: initialize postbox event
self.user = ko.observable(new User()).publishOn('userEdit');
self.showEdit = function (user) {
// #QUESTION 1: how do I send this object to the
// users-form component. ko.postbox?
// #ANSWER 1: change the observable
self.user(user);
console.log('show', user);
};
},
template: ''
+ '<ul data-bind="foreach: users">'
+ '<li>'
+ '<button data-bind="click: $parent.showEdit">Edit</button>'
+ ' <span data-bind="text: name"></span>'
+ '</li>'
+ '</ul>'
},
// Form component, initially in a separate file
// (small modifs so all can be in the same file for this demo)
cmpform = {
viewModel: function () {
var self = this;
// #QUESTION 2: how do I recept the object sent by the
// list?
// #ANSWER 2: make the observable subscribe to event
self.user = ko.observable(new User()).subscribeTo('userEdit');
self.save = function () {
// #QUESTION 3: how do I notify the users-list cmp
// that object has changed? ko.postbox?
window.alert('save ' + ko.toJSON(self.user()));
console.log('save');
};
},
// #ANSWER 2: call user() with parenthesis to access properties
template: ''
+ '<form>'
+ '<p>Edit user <span data-bind="text: user().name"></span> '
+ 'with id <span data-bind="text: user().id"></span></p>'
+ '<input data-bind="textInput: user().name" />'
+ '<button data-bind="click: save">Save</button>'
+ '</form>'
};
// KO bootstrap, initially in a 3rd file
// (small modifs so all can be in the same file for this demo)
ko.components.register('users-list', cmplist);
ko.components.register('users-form', cmpform);
ko.applyBindings({});
ul {
border: 1px solid blue;
list-style: none;
float: left;
}
li {
border: 1px solid green;
}
form {
border: 1px solid red;
float: right;
margin-top: 20px;
}
ul, li, form {
padding: 5px;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-postbox/0.5.2/knockout-postbox.min.js"></script>
</head>
<body>
<users-list></users-list>
<users-form></users-form>
</body>
</html>
I have 2 Dojo Dijit ContentPane's side by side. I want to show/hide one of them, and have the other one stretch dynamically as needed. I am using an ESRI mapping example which uses 'dijit.layout.BorderContainer'. The "divRightMenu" will show/hide itself correctly, but, when opened, rather than pushing the "mapDiv" Div, it just appears on top of it. I want the "mapDiv" div to dynamically resize itself depending on the visible state of the "divRightMenu" div.
I'm including the full page code below - I have already experimented with style.Display = Block / None, style.Visibility = Visible/Hidden, as well as trying to dynamically set the width of divRightMenu from 1 pixel to 150 pixels. In all cases, divRightMenu appears "on top of" mapDiv, rather than "pushing" it like I want. If I change the code so that divRightMenu is visible by default on page load, then what happens when i hide it is it disappears, but the blank spot it once occupied still remains. Surely this is something simple I'm missing?
In the past (standard CSS), I would combine "float:left/right" with "overflow:hidden", and display:block/none, and could easily achieve the effect I'm after, but with Dojo/Dijit i'm not sure what i'm missing. I experimented with various combinations of float/overflow on the inline styling of the 2 DIV tags in question, but was unable to get it to work. I also noted that one poster mentioned that he programmatically created his dijit ContentPanes on the fly to overcome the issue, but I was hoping for a solution other than this (i need all the settings from the div's content to be retained between showing/hiding the div, and i'm not sure if re-creating it on the fly will allow for this).
Here are the 2 threads I found that touch on the topic:
Dojo Toggle Hide and Show Divs
Toggling the display of a Dojo dijit
These mainly deal with being able to hide the div or not. In my case I'm able to hide/show it, but just not able to get the desired auto-resize behavior from the remaining DIV.
In any case, full code sample is included below - any help would be appreciated:
Main Index.htm Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="generator" content="HTML Tidy for Windows (vers 14 February 2006), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="layout.css">
<link rel="stylesheet" type="text/css"href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.2/js/dojo/dijit/themes/tundra/tundra.css">
<script type="text/javascript">
var djConfig = {
parseOnLoad: true
}
function ToggleVisibility(id)
{
//if (dijit.byId(id).domNode.style.width == '150px') {
if (dijit.byId(id).domNode.style.display == 'block') {
dijit.byId(id).domNode.style.display = 'none';
//dijit.byId(id).domNode.style.width = "1px";
//dojo.style(id, "visibility", "hidden");
}
else {
//dijit.byId(id).domNode.style.width = "150px";
dijit.byId(id).domNode.style.display = 'block';
//dojo.style(id, "visibility", "visible");
}
dijit.byId(id).resize();
//dijit.byId("mapDiv").resize();
}
</script>
<script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.2"></script>
<script src="layout.js" type="text/javascript"></script>
<script type="text/javascript">
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.ContentPane");
</script>
</head>
<body class="tundra">
<!--TOPMOST LAYOUT CONTAINER-->
<div style="border:4px solid purple;width:100%;height:100%;" id="mainWindow" dojotype="dijit.layout.BorderContainer" design="headline" gutters="false">
<!--HEADER SECTION-->
<div id="header" style="border:4px solid red;height:85px;" dojotype="dijit.layout.ContentPane" region="top">
<div id="headerArea" style="border:2px solid black;height:50px;" dojotype="dijit.layout.ContentPane" region="top">Logo Here</div>
<div id="navMenuArea" style="border:2px solid green;height:35px;" dojotype="dijit.layout.ContentPane" region="top">Menu Here | <input type="button" onClick="ToggleVisibility('divRightMenu');" value="Toggle Right Menu"/></div>
</div>
<!--CENTER SECTION-->
<!--CENTER CONTAINER-->
<div id="mapDiv" style="border:2px solid green;margin:2px;" dojotype="dijit.layout.ContentPane" region="center"></div>
<!--RIGHT CONTAINER-->
<div id="divRightMenu" style="display:none;width:150px;border:2px solid orange;background-color:whitesmoke;" dojotype="dijit.layout.ContentPane" region="right">
Right Menu
</div>
<!--FOOTER SECTION-->
<div style="border:4px solid blue;height:50px;" id="footer" dojotype="dijit.layout.ContentPane" region="bottom">
Footer Here
</div>
</div>
</body>
</html>
layout.js Code:
dojo.require("esri.map");
var resizeTimer;
var map;
function init() {
var initialExtent = new esri.geometry.Extent(-125.0244140625, 14.4580078125, -80.0244140625, 59.4580078125, new esri.SpatialReference({
wkid: 4326
}));
map = new esri.Map("mapDiv", {
extent: initialExtent
});
dojo.connect(map, 'onLoad', function(theMap) {
dojo.connect(dijit.byId('mapDiv'), 'resize', function() {
resizeMap();
});
});
var url = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer";
var tiledLayer = new esri.layers.ArcGISTiledMapServiceLayer(url);
map.addLayer(tiledLayer);
}
//Handle resize of browser
function resizeMap() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
map.resize();
map.reposition();
}, 800);
}
//show map on load
dojo.addOnLoad(init);
layout.css Code:
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color:#FFF;
overflow:hidden;
font-family: "Trebuchet MS";
}
#header {
background-color:#FFF;
color:#999;
font-size:16pt;
font-weight:bold;
}
#headerArea {
text-align:left;
}
#navMenuArea {
text-align:right;
/*background:url(toolbar_bg.png) repeat #6788a2;*/
}
#topmenu {
background-color:#FFF;
color:#999;
font-size:16pt;
text-align:right;
font-weight:bold;
}
#footer {
background-color:#FFF;
color:#999;
font-size:10pt;
text-align:center;
}
Use a dijit/layout/BorderContainer, place the 2 contentpanes inside it, setting one of the 2 containers' region property to "center" and the other one to "right".
When you want to resize one of the contentpanes, call their "resize" method with an object containing the "w" property.
After calling resize on the contentpane, call "layout" on the border container.
Example :
require([
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/form/Button",
"dojo/domReady!"
], function(BorderContainer, ContentPane, Button){
var container = new BorderContainer({
design : "headline",
gutters : false
}, "container");
var pane1 = new ContentPane({
region : "center",
id : "pane1"
});
var pane2 = new ContentPane({
region : "right",
id : "pane2"
});
var toolbar = new ContentPane({
region : "bottom",
id : "toolbar"
});
var btn = new Button({
label : "Change right side",
onClick : function(){
pane2.resize({ w : Math.random() * pane2.get("w") });
container.layout();
}
});
toolbar.addChild(btn);
container.addChild(pane1);
container.addChild(pane2);
container.addChild(toolbar);
container.startup();
});
See this fiddle : http://jsfiddle.net/psoares/vEsy7/