Related
I Have a custom module website_decimal_quantity. after installing this module, In the website shop cart, when the user clicks on the + or - button to adjust quantity, It should add or deduct .1 value from it. i find out that a function onclickaddcartjson in the sale.variantmixin is responsible for the button click.i tried to extend the onclickaddcartjson function that present in the website_sale.website_sale. but it does not work.
Thanks For the Attention
My code is like :
publicWidget.registry.WebsiteSale.include({
onClickAddCartJSON: function (ev) {
ev.preventDefault();
var $link = $(ev.currentTarget);
var $input = $link.closest('.input-group').find("input");
var min = parseFloat($input.data("min") || 0);
var max = parseFloat($input.data("max") || Infinity);
var previousQty = parseFloat($input.val() || 0, 10);
var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) + previousQty;
var newQty = quantity > min ? (quantity < max ? quantity : max) : min;
if (newQty !== previousQty) {
$input.val(newQty).trigger('change');
}
return false;
},
_changeCartQuantity: function ($input, value, $dom_optional, line_id, productIDs) {
_.each($dom_optional, function (elem) {
$(elem).find('.js_quantity').text(value);
productIDs.push($(elem).find('span[data-product-id]').data('product-id'));
});
$input.data('update_change', true);
this._rpc({
route: "/shop/cart/update_json",
params: {
line_id: line_id,
product_id: parseInt($input.data('product-id'), 10),
set_qty: value
},
}).then(function (data) {
$input.data('update_change', false);
var check_value = parseFloat($input.val());
if (isNaN(check_value)) {
check_value = 1;
}
if (value !== check_value) {
$input.trigger('change');
return;
}
if (!data.cart_quantity) {
return window.location = '/shop/cart';
}
wSaleUtils.updateCartNavBar(data);
$input.val(data.quantity);
$('.js_quantity[data-line-id='+line_id+']').val(data.quantity).text(data.quantity);
if (data.warning) {
var cart_alert = $('.oe_cart').parent().find('#data_warning');
if (cart_alert.length === 0) {
$('.oe_cart').prepend('<div class="alert alert-danger alert-dismissable" role="alert" id="data_warning">'+
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> ' + data.warning + '</div>');
}
else {
cart_alert.html('<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> ' + data.warning);
}
$input.val(data.quantity);
}
});
},
_onChangeCartQuantity: function (ev) {
var $input = $(ev.currentTarget);
if ($input.data('update_change')) {
return;
}
var value = parseFloat($input.val());
if (isNaN(value)) {
value = 1;
}
var $dom = $input.closest('tr');
// var default_price = parseFloat($dom.find('.text-danger > span.oe_currency_value').text());
var $dom_optional = $dom.nextUntil(':not(.optional_product.info)');
var line_id = parseInt($input.data('line-id'), 10);
var productIDs = [parseInt($input.data('product-id'), 10)];
this._changeCartQuantity($input, value, $dom_optional, line_id, productIDs);
},
})
The change that I made is in _onclickaddcartjson; change the line
var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) + previousQty;
and in _changeCartQuantity, change the check_value into:
var check_value = parseFloat($input.val())
And in _onChangeCartQuantity, change the value into:
var value = parseFloat($input.val()).
Even if I made these changes in source file without my custom module, the quantity increase or decrease by .1. But it automatically turns into an integer value. That means when I click on the + button, the value changes to 1.1, but it immediately changes to 1. Also, if I click on the - button, it will changes to 2.9 from 3, then it changes to 2 as its value. If anybody has an idea about this please share. Thanks for the attention.
Yes, it 's possible as the type of the underlying field in model SaleOrderLine is Float. And in website_sale/models/sale_order.py : int(sum(order.mapped('website_order_line.product_uom_qty'))) needs to be reülaced by: sum(order.mapped('website_order_line.product_uom_qty')):
class SaleOrderLine(models.Model):
_name = 'sale.order.line'
product_uom_qty = fields.Float(string='Quantity', digits='Product Unit of Measure', required=True, default=1.0)
#api.depends('order_line.product_uom_qty', 'order_line.product_id')
def _compute_cart_info(self):
for order in self:
order.cart_quantity = sum(order.mapped('website_order_line.product_uom_qty'))
order.only_services = all(l.product_id.type in ('service', 'digital') for l in order.website_order_line)
The underlying python method to add quantity is located in addons module website_sale/models/sale_oder.py :
def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs):
""" Add or set product quantity, add_qty can be negative """
self.ensure_one()
product_context = dict(self.env.context)
product_context.setdefault('lang', self.sudo().partner_id.lang)
SaleOrderLineSudo = self.env['sale.order.line'].sudo().with_context(product_context)
...
...which is called by 2 methods in website_sale/controllers/main.py :
#http.route(['/shop/cart/update'], type='http', auth="public", methods=['GET', 'POST'], website=True, csrf=False)
def cart_update(self, product_id, add_qty=1, set_qty=0, **kw):
AND
#http.route(['/shop/cart/update_json'], type='json', auth="public", methods=['POST'], website=True, csrf=False)
def cart_update_json(self, product_id, line_id=None, add_qty=None, set_qty=None, display=True):
"""This route is called when changing quantity from the cart or adding
a product from the wishlist."""
"""This route is called when adding a product to cart (no options)."""
This controller method cart_update_json is called in sale/.../js/variant_mixin.js by:
onClickAddCartJSON: function (ev) {
ev.preventDefault();
var $link = $(ev.currentTarget);
var $input = $link.closest('.input-group').find("input");
var min = parseFloat($input.data("min") || 0);
var max = parseFloat($input.data("max") || Infinity);
var previousQty = parseFloat($input.val() || 0, 10);
var quantity = ($link.has(".fa-minus").length ? -1 : 1) + previousQty;
var newQty = quantity > min ? (quantity < max ? quantity : max) : min;
if (newQty !== previousQty) {
$input.val(newQty).trigger('change');
}
return false;
},
...where: var quantity = ($link.has(".fa-minus").length ? -1 : 1) + previousQty; shows us that is incremented +1 oder -1
That s why you need to override this function in website_sale/.../website_sale.js to integrate:
var $parent = $(ev.target).closest('.js_product');
var product_id = this._getProductId($parent);
if product_id == yourspecificproductid
var quantity = ($link.has(".fa-minus").length ? -0.1 : 0.1) +
previousQty;
else
var quantity = ($link.has(".fa-minus").length ? -1 : 1) +
previousQty;
When quantity input value is changed automatically, it might be caused by parseInt($input.val()) in _onChangeCartQuantity in the file: website_sale.js:
_onChangeCartQuantity: function (ev) {
var $input = $(ev.currentTarget);
if ($input.data('update_change')) {
return;
}
var value = parseFloat($input.val() || 0, 10);
if (isNaN(value)) {
value = 1;
}
var $dom = $input.closest('tr');
// var default_price = parseFloat($dom.find('.text-danger > span.oe_currency_value').text());
var $dom_optional = $dom.nextUntil(':not(.optional_product.info)');
var line_id = parseInt($input.data('line-id'), 10);
var productIDs = [parseInt($input.data('product-id'), 10)];
this._changeCartQuantity($input, value, $dom_optional, line_id, productIDs);
},
My problem is that I am trying to get an access token from Spotify, but my window.addEventListener("message, function() {...}") is never triggered. Refer to the code below:
mounted(){
this.$nextTick(function() {
function login(callback) {
var CLIENT_ID = 'd3ebae5610894ca48c9f66794214252b';
var REDIRECT_URI = 'http://localhost:8080/spotify';
function getLoginURL(scopes) {
console.log('url')
return 'https://accounts.spotify.com/authorize?client_id=' + CLIENT_ID +
'&redirect_uri=' + encodeURIComponent(REDIRECT_URI) +
'&scope=' + encodeURIComponent(scopes.join(' ')) +
'&response_type=token';
}
var url = getLoginURL([
'user-read-email'
]);
var width = 450,
height = 730,
left = (screen.width / 2) - (width / 2),
top = (screen.height / 2) - (height / 2);
var w = window.open(url,
'Spotify',
'menubar=no,location=no,resizable=no,scrollbars=no,status=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left
);
window.addEventListener("message", function(event) {
var hash = JSON.parse(event.data);
console.log(JSON.parse(event.data))
if (hash.type == 'access_token') {
callback(hash.access_token);
}
}, false);
}
var loginButton = document.getElementById('btn-login');
loginButton.addEventListener('click', function() {
console.log('click the button')
login(function(accessToken) {
console.log(accessToken)
});
});
})}
I have a question about the pie chart in c3.js.
How can I add the total count of a pie chart in the title??
var title = new Array('data1.sql','data2.sql')
var dtitle = new Array('title1','title2')
var chart = new Array('chart0', 'chart1')
for(var i = 0; i < title.length; i++){
chart[i] = c3.generate({
bindto : '#chart' + i,
size: {
height: 550,
width: 800
},
data : {
url : '/json/sql/data/test/' + title[i],
mimeType : 'json',
type : 'donut'
},
donut: {
title: dtitle[i] + ' - Total:' ,
label: {
format: function(value, ratio, id) {
return value;
}
}
}
});
}
The annoying thing here is that the title option can take a function, but the chart variable is not initialised within it so using the c3 api methods can't be done at this point.
So the best (maybe only) way is to add an onrendered callback that adds up the data as you'd need to anyways and then replace the text in the chart's title text using a spot of d3:
onrendered: function () {
var data = this.api.data();
var total = data.reduce (function (subtotal, t) {
return subtotal + t.values.reduce (function (subsubtotal,b) { return subsubtotal + b.value; }, 0);
}, 0);
d3.select(this.config.bindto + " .c3-chart-arcs-title").text("Total: "+total);
}
Edit: If you want it to keep track of a total as you hide/show series use this
var data = this.api.data.shown.call (this.api);
instead of
var data = this.api.data();
I've created a radial dial using the Raphael-js library and it works as should on page load. It's embedded in a responsive layout so I want it to resize according to it's container, which it does. However, the new container size makes the mouse events inaccurate. When I resize it back to what it was on page load, it works fine.
function RadialDial(paperId, opts) {
var thisObj = this;
this.dialParent = document.querySelector(paperId);
this.divPaper = this.dialParent.querySelector('.radialDial');
this.divPaperW = this.divPaper.clientWidth;
this.scaleRatio = this.divPaperW / 250;
this.outputEle = this.dialParent.querySelector('.dialOutput .val');
this.btnPlus = this.dialParent.querySelector('.btnPlus');
this.btnMinus = this.dialParent.querySelector('.btnMinus');
this.debug = this.dialParent.querySelector('.debug');
this.opts = {
dialCenter: this.divPaperW / 2,
dialRadius: this.divPaperW / 2,
startA: 155,
endA: 25,
arcCentralA: 230,
maxRange: 12,
minRange: 3,
postText: false,
rangeSteps: 3
}
this.currNeedleA;
this.rangeAngles = [];
this.setOptions(opts);
this.paper = Raphael(this.divPaper, this.opts.dialRadius * 2, this.opts.dialRadius * 2);
this.rangeDivisions = Raphael.rad(this.opts.arcCentralA / (this.opts.maxRange - this.opts.minRange));
this.arcStartX = (this.opts.dialCenter + ((this.opts.dialRadius - (30 * this.scaleRatio)) * Math.cos(Raphael.rad(this.opts.startA)))).toString();
this.arcStartY = (this.opts.dialCenter + ((this.opts.dialRadius - (30 * this.scaleRatio)) * Math.sin(Raphael.rad(this.opts.startA)))).toString();
var currSectorX = this.arcStartX;
var currSectorY = this.arcStartY;
var dialFaceAtts = (Raphael.svg) ? {fill: "r#ffffff-#ffffff:85-#999999:75-#cccccc:57-#999999", stroke: "none"} : {fill: "#ffffff", stroke: "#999999", "stroke-width": (1 * this.scaleRatio)};
this.dialFace = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, this.opts.dialRadius).attr(dialFaceAtts);
var dialFaceRim = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, (102 * this.scaleRatio)).attr({fill: "none", "stroke-width": (8 * this.scaleRatio), stroke: "#eeeeee", "stroke-opacity": 0.4});
var currSectorAngle = Raphael.rad(this.opts.startA);
var rangeSet = this.paper.set();
for (var i = this.opts.minRange; i <= (this.opts.maxRange); i++) {
currSectorX = (this.opts.dialCenter + ((this.opts.dialRadius - (40 * this.scaleRatio)) * Math.cos(currSectorAngle))).toString();
currSectorY = (this.opts.dialCenter + ((this.opts.dialRadius - (40 * this.scaleRatio)) * Math.sin(currSectorAngle))).toString();
if (i % this.opts.rangeSteps == 0) {
var rangeTxt = this.paper.text(currSectorX, currSectorY, i).attr({fill: "#00a2d8", "font-size": (22 * this.scaleRatio).toString()});
rangeSet.push(rangeTxt);
this.rangeAngles[i] = Raphael.deg(this.rangeDivisions * (i - (this.opts.minRange)));
}
currSectorAngle = currSectorAngle + this.rangeDivisions;
}
this.clickArea = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, this.opts.dialRadius).attr({fill: "red", "fill-opacity": 0, stroke: "none"});
this.needle = this.paper.path("M" + (this.arcStartX).toString() + "," + (this.arcStartY).toString() +
"L" + (this.opts.dialCenter * (138.89401 / this.opts.dialCenter) * this.scaleRatio).toString() + "," + (this.opts.dialCenter * (107.45764 / this.opts.dialCenter) * this.scaleRatio).toString() +
"L" + (this.opts.dialCenter * (147.34637 / this.opts.dialCenter) * this.scaleRatio).toString() + "," + (this.opts.dialCenter * (125.5838 / this.opts.dialCenter) * this.scaleRatio).toString() + "z").attr({fill: '#0058b6', stroke: "none"});/* */
var needleLine = this.paper.path("M" + (this.opts.dialCenter + (18 * this.scaleRatio)).toString() + ' ' + (this.opts.dialCenter - (8 * this.scaleRatio)).toString() + ", L" + this.arcStartX + "," + this.arcStartY).attr({stroke: "#ffffff", "stroke-width": .7});
var centerCircle = this.paper.circle(this.opts.dialCenter, this.opts.dialCenter, (12 * this.scaleRatio)).attr({fill: "#0058b6", stroke: "none"});
this.needleSet = this.paper.set();
this.needleSet.push(this.needle, needleLine);
this.dialSet = this.paper.set();
this.dialSet.push(dialFaceRim, this.dialFace, this.clickArea, this.needleSet, rangeSet, centerCircle, needleLine);
this.paper.setViewBox(0, 0, this.opts.dialRadius * 2, this.opts.dialRadius * 2, true);
this.paper.canvas.setAttribute('preserveAspectRatio', 'none');
this.needleSet.push(this.needle);
this.needleSet.data('thisObj', thisObj);
this.needleSet.data('paperObj', this.paper.canvas);
this.setNeedleDrag();
this.dialFaceClick();
}
RadialDial.prototype = {
constructor: RadialDial,
setOptions: function (opts) {
for (key in opts) {
if (!opts.hasOwnProperty(key)) {
continue;
}
this.opts[key] = opts[key];
}
},
drawDial: function () {
},
elePosition: function (ele) {
var eleX = 0;
var eleY = 0;
while (ele) {
eleX += (ele.offsetLeft - ele.scrollLeft + ele.clientLeft);
eleY += (ele.offsetTop - ele.scrollTop + ele.clientTop);
ele = ele.offsetParent;
}
return {x: eleX, y: eleY};
},
moveNeedle: function (dx, dy, x, y, e) {
var classObj = this.data('thisObj');
var rectObject = classObj.divPaper.getBoundingClientRect();
var paperXY = classObj.elePosition(classObj.divPaper);
var mouseX, mouseY;
mouseX = e.clientX - rectObject.left;
mouseY = e.clientY - rectObject.top;
var needleA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['x'], classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['y']);
var newA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, mouseX, mouseY);
var rotateAngle = (360 - needleA) + newA;
if (!(newA > (360 - classObj.opts.startA) && newA < (360 - classObj.opts.endA))) {
classObj.needleSet.transform('r' + rotateAngle + "," + classObj.opts.dialCenter + "," + classObj.opts.dialCenter);
}
},
setNeedleDrag: function () {
var startDrag = function () {
}, dragger = this.moveNeedle,
endDrag = this.findNearestStep;
this.needleSet.drag(dragger, startDrag, endDrag);
},
dialFaceClick: function () {
var classObj = this;
this.clickArea.node.onclick = function (e) {
var e = e || window.event;
var rectObject = classObj.divPaper.getBoundingClientRect();
var mouseX, mouseY;
mouseX = e.clientX - rectObject.left;
mouseY = e.clientY - rectObject.top;
var needleA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['x'], classObj.needle.getPointAtLength(classObj.needle.getTotalLength())['y']);
var newA = Raphael.angle(classObj.opts.dialCenter, classObj.opts.dialCenter, mouseX, mouseY);
var rotateAngle = (360 - needleA) + newA;
if (!(newA > (360 - classObj.opts.startA) && newA < (360 - classObj.opts.endA))) {
classObj.needleSet.transform('r' + rotateAngle + "," + classObj.opts.dialCenter.toString() + "," + classObj.opts.dialCenter.toString());
}
classObj.findNearestStep(classObj);
return false;
}
},
findNearestStep: function (obj) {
var classObj = (obj.target || obj.srcElement) ? this.data('thisObj') : obj;
var currVal = Math.round((Raphael.rad(classObj.needle.matrix.split().rotate) * ((classObj.opts.maxRange - classObj.opts.minRange) / Raphael.rad(classObj.opts.arcCentralA))) + classObj.opts.minRange);
var nextVal = currVal;
var prevVal, newA, index;
if (currVal % classObj.opts.rangeSteps != 0) {
while (nextVal % classObj.opts.rangeSteps != 0) {
nextVal = nextVal + 1;
}
if ((nextVal - currVal) > (classObj.opts.rangeSteps / 2)) {
nextVal = nextVal - classObj.opts.rangeSteps;
}
index = nextVal;
} else {
index = currVal;
}
newA = classObj.rangeAngles[index];
classObj.needleSet.transform('r' + (newA) + "," + classObj.opts.dialCenter + "," + classObj.opts.dialCenter);
}
}
Here is my fiddle, http://jsfiddle.net/fiddle_fish/rvLo1cuy/ , dragging the needle makes it follow the mouse pointer closely. Now click the "Resize container" link, whilst the needle still moves it doesn't follow the pointer closely. It seems the resize has created an offset for the mouse event target area.
I've tried changing the viewbox settings, width/height values,removing events and reapplying them, deleting the dial on resize and redrawing the dial but nothing works.
Tried, raphael js, calculate setViewBox width height to fix window
and, raphael js, resize canvas then setViewBox to show all elements
Neither works. :(
I sussed this out. I've multiplied the mouse x-y coordinates with a ratio based on the paper size onload/resize. Works a treat :)
I just encountered the same issue. Basically, on window resize I recalculate the "scale" i.e. the ratio of the svg element's viewBox to its current height/width.
Here's my solution:
var scale = {
x:1,
y:1
}
$(window).resize(function(){
scale = getScale(paper);
})
function getScale(paper){
var x = paper.canvas.viewBox.baseVal.width/$(paper.canvas).width();
var y = paper.canvas.viewBox.baseVal.height/$(paper.canvas).height();
return {
x:x,
y:y
}
}
and then in my "move" function, I added a multiplier to dx and dy:
var move = function (dx, dy,x,y) {
var X = this.cx + dx * scale.x,
Y = this.cy + dy * scale.y;
this.attr({cx: X, cy: Y});
}
For context, the move function is used like so:
var start = function(){
this.cx = this.attr("cx"),
this.cy = this.attr("cy");
}, move = function (dx, dy,x,y) {
var X = this.cx + dx * scale.x,
Y = this.cy + dy * scale.y;
this.attr({cx: X, cy: Y});
}
raphael_element.drag(move,start);
Note that there's some JQuery thrown in here that you could easily do without.
I'm trying to add a button to a custom pallete to call a function "uiFileInputDlg" which is in the workspace that uses the widget. The upbtn appears on the pallete, but it is not triggering the DoUpload function which is connected in postcreate to then call on "uiFileInputDlg".
works flawlessly in firefox.
we're user dojo 1.7.2
-----------THE TEMPLATE-------------------------
<div class="dijitInline dijitColorPalette">
<div class="dijitColorPaletteInner" data-dojo-attach-point="divNode" role="grid" tabIndex="${tabIndex}">
</div>
<button type="button" id="upbtn"
data-dojo-type="dijit.form.Button"
data-dojo-props="id:'upbtn'"
data-dojo-attach-point="btnUpNode">
Upload New Image
</button>
</div>
-------------------------THE WIDGET--------------------------
//dojo.provide("meemli.UploadPalette");
define([ 'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dojo/i18n!dijit/nls/common',
'dojo/text!./templates/UploadPalette.html',
'dijit/_WidgetsInTemplateMixin',
'dojo/_base/lang'
],
function(declare, w, t, i18n, template, witm, lang){
console.log('meemli.UploadPalette: Requiring dijit/nls/common.js INSTEAD OF dojo/nls/common' + i18n.invalidMessage);
return declare("meemli.UploadPalette",
[dijit._Widget, dijit._Templated],
{
// summary: A keyboard accessible color-picking widget
// description:
// Grid showing various colors, so the user can pick a certain color
// Can be used standalone, or as a popup.
//
// example:
// | <div dojoType="dijit.ColorPalette"></div>
//
// example:
// | var picker = new dijit.ColorPalette({ },srcNode);
// | picker.startup();
//
// defaultTimeout: Number
// number of milliseconds before a held key or button becomes typematic
defaultTimeout: 500,
// timeoutChangeRate: Number
// fraction of time used to change the typematic timer between events
// 1.0 means that each typematic event fires at defaultTimeout intervals
// < 1.0 means that each typematic event fires at an increasing faster rate
timeoutChangeRate: 0.90,
// palette: String
// Size of grid, either "7x10" or "3x4".
palette: "3x3",
//_value: String
// The value of the selected color.
value: null,
//_currentFocus: Integer
// Index of the currently focused color.
_currentFocus: 0,
// _xDim: Integer
// This is the number of colors horizontally across.
_xDim: null,
// _yDim: Integer
/// This is the number of colors vertically down.
_yDim: null,
// _palettes: Map
// This represents the value of the colors.
// The first level is a hashmap of the different arrays available
// The next two dimensions represent the columns and rows of colors.
_palettes: {
"3x3": [],
"3x2": ["/images/icons/1.png", "/images/icons/2.png", "/images/icons/3.png","/images/icons/4.png", "/images/icons/5.png", "/images/icons/6.png"]
},
// _imagePaths: Map
// This is stores the path to the palette images
// _imagePaths: {
// "3x3": dojo.moduleUrl("dijit", "templates/icons3x3.png")
// },
// _paletteCoords: Map
// This is a map that is used to calculate the coordinates of the
// images that make up the palette.
_paletteCoords: {
"leftOffset": 3, "topOffset": 3,
"cWidth": 50, "cHeight": 50
},
// templatePath: String
// Path to the template of this widget.
// templateString: dojo.cache("meemli", "templates/UploadPalette.html"),
templateString: template,
// _paletteDims: Object
// Size of the supported palettes for alignment purposes.
_paletteDims: {
"3x3": {"width": "156px", "height": "156px"}, // 48*3 + 3px left/top border + 3px right/bottom border...
"3x2": {"width": "156px", "height": "109px"} // 48*3 + 3px left/top border + 3px right/bottom border...
},
// tabIndex: String
// Widget tabindex.
maxCols: 3,
tabIndex: "0",
_curIndex: 0,
DoUpload: function(){
alert('hello');
uiFileInputDlg(); // function out in the workspace
},
_addImage: function(url) {
row = Math.floor(this._curIndex / this.maxCols);
col = this._curIndex - (row * this.maxCols);
this._curIndex++;
this._yDim = Math.floor(this._curIndex / this.maxCols);
this._xDim = this._curIndex - (row * this.maxCols);
var imgNode = dojo.doc.createElement("img");
imgNode.src = url;
//imgNode.style.height = imgNode.style.width = "48px";
var cellNode = dojo.doc.createElement("span");
cellNode.appendChild(imgNode);
cellNode.connectionRefs = new Array();
dojo.forEach(["Dijitclick", "MouseEnter", "Focus", "Blur"], function(handler) {
cellNode.connectionRefs.push(this.connect(cellNode, "on" + handler.toLowerCase(), "_onCell" + handler));
}, this);
this.divNode.appendChild(cellNode);
var cellStyle = cellNode.style;
cellStyle.top = this._paletteCoords.topOffset + (row * this._paletteCoords.cHeight) + "px";
cellStyle.left = this._paletteCoords.leftOffset + (col * this._paletteCoords.cWidth) + "px";
cellStyle.height = this._paletteCoords.cHeight + "px";
cellStyle.width = this._paletteCoords.cWidth + "px";
// console.debug( "tlhw: " + cellStyle.top + ", " + cellStyle.left + ", " + cellStyle.height + ", " + cellStyle.width );
// adjust size when the bits come...
// this.xh = this.xw = "32px";
//console.log('this.xh => ' + this.xh);
dojo.connect( imgNode,"onload", this, function() {
//console.log('IN: CONNECT...this.xh => ' + this.xh);
this.xh = imgNode.height;
this.xw = imgNode.width;
this.xh = (this.xh==0) ? this.xh="32px" : (this.xh + "");
this.xw = (this.xw==0) ? this.xw="32px" : (this.xw + "");
// var h = parseInt( this.xh );
// var w = parseInt( this.xw );
var hArr = this.xh.split('p');
var wArr = this.xw.split('p');
var h =hArr[0];
var w = wArr[0];
var THUMBNAIL_MAX_WIDTH = 50;
var THUMBNAIL_MAX_HEIGHT = 50;
var hLim = Math.min(THUMBNAIL_MAX_HEIGHT, this._paletteCoords.cHeight);
var wLim = Math.min(THUMBNAIL_MAX_WIDTH, this._paletteCoords.cWidth);
var scale = 1.0;
if( h > hLim || w > wLim ) {
if( h / w < 1.0 ) { // width is bigger than height
scale = wLim / w;
}
else {
scale = hLim / h;
}
}
imgNode.style.height = (scale * h) + "px";
imgNode.style.width = (scale * w) + "px";
console.debug( imgNode.src + ' loaded.'
+ "old: h " + h + ", w " + w + ", scale " + scale
+ ". new: h " + imgNode.style.height + ", w " + imgNode.style.width );
} );
if(dojo.isIE){
// hack to force event firing in IE
// image quirks doc'd in dojox/image/Lightbox.js :: show: function.
// imgNode.src = imgNode.src;
}
dojo.attr(cellNode, "tabindex", "-1");
dojo.addClass(cellNode, "imagePaletteCell");
dijit.setWaiRole(cellNode, "gridcell");
cellNode.index = this._cellNodes.length;
this._cellNodes.push(cellNode);
},
_clearImages: function() {
for(var i = 0; i < this._cellNodes.length; i++) {
this._cellNodes[i].parentNode.removeChild(this._cellNodes[i]);
}
this._currentFocus = 0;
this._curIndex = 0;
this._yDim = 0;
this._xDim = 0;
this._cellNodes = [];
},
setImages: function(imageList) {
this._clearImages();
for(var i = 0; i < imageList.length; i++) {
this._addImage(imageList[i]);
}
},
postCreate: function(){
// A name has to be given to the colorMap, this needs to be unique per Palette.
dojo.mixin(this.divNode.style, this._paletteDims[this.palette]);
// this.imageNode.setAttribute("src", this._imagePaths[this.palette]);
this.domNode.style.position = "relative";
this._cellNodes = [];
this.setImages(this._palettes[this.palette]);
this.connect(this.divNode, "onfocus", "_onDivNodeFocus");
this.connect(this.btnUpNode, "onclick", "DoUpload");
// Now set all events
// The palette itself is navigated to with the tab key on the keyboard
// Keyboard navigation within the Palette is with the arrow keys
// Spacebar selects the color.
// For the up key the index is changed by negative the x dimension.
var keyIncrementMap = {
UP_ARROW: -this._xDim,
// The down key the index is increase by the x dimension.
DOWN_ARROW: this._xDim,
// Right and left move the index by 1.
RIGHT_ARROW: 1,
LEFT_ARROW: -1
};
for(var key in keyIncrementMap){
this._connects.push(dijit.typematic.addKeyListener(this.domNode,
{keyCode:dojo.keys[key], ctrlKey:false, altKey:false, shiftKey:false},
this,
function(){
var increment = keyIncrementMap[key];
return function(count){ this._navigateByKey(increment, count); };
}(),
this.timeoutChangeRate, this.defaultTimeout));
}
},
focus: function(){
// summary:
// Focus this ColorPalette. Puts focus on the first swatch.
this._focusFirst();
},
onChange: function(url, hsz, wsz){
// summary:
// Callback when a image is selected.
// url, hsz, wsz, strings
// height and width string .
// console.debug("img selected: "+url);
},
_focusFirst: function(){
this._currentFocus = 0;
var cellNode = this._cellNodes[this._currentFocus];
window.setTimeout(function(){dijit.focus(cellNode);}, 0);
},
_onDivNodeFocus: function(evt){
// focus bubbles on Firefox 2, so just make sure that focus has really
// gone to the container
if(evt.target === this.divNode){
this._focusFirst();
}
},
_onFocus: function(){
// while focus is on the palette, set its tabindex to -1 so that on a
// shift-tab from a cell, the container is not in the tab order
dojo.attr(this.divNode, "tabindex", "-1");
},
_onBlur: function(){
this._removeCellHighlight(this._currentFocus);
// when focus leaves the palette, restore its tabindex, since it was
// modified by _onFocus().
dojo.attr(this.divNode, "tabindex", this.tabIndex);
},
_onCellDijitclick: function(/*Event*/ evt){
// summary:
// Handler for click, enter key & space key. Selects the color.
// evt:
// The event.
var target = evt.currentTarget;
if (this._currentFocus != target.index){
this._currentFocus = target.index;
window.setTimeout(function(){dijit.focus(target);}, 0);
}
this._selectColor(target);
dojo.stopEvent(evt);
},
_onCellMouseEnter: function(/*Event*/ evt){
// summary:
// Handler for onMouseOver. Put focus on the color under the mouse.
// evt:
// The mouse event.
var target = evt.currentTarget;
window.setTimeout(function(){dijit.focus(target);}, 0);
},
_onCellFocus: function(/*Event*/ evt){
// summary:
// Handler for onFocus. Removes highlight of
// the color that just lost focus, and highlights
// the new color.
// evt:
// The focus event.
this._removeCellHighlight(this._currentFocus);
this._currentFocus = evt.currentTarget.index;
dojo.addClass(evt.currentTarget, "imagePaletteCellHighlight");
},
_onCellBlur: function(/*Event*/ evt){
// summary:
// needed for Firefox 2 on Mac OS X
this._removeCellHighlight(this._currentFocus);
},
_removeCellHighlight: function(index){
dojo.removeClass(this._cellNodes[index], "imagePaletteCellHighlight");
},
_selectColor: function(selectNode){
// summary:
// This selects a color. It triggers the onChange event
// area:
// The area node that covers the color being selected.
var img = selectNode.getElementsByTagName("img")[0];
this.onChange(this.value = img.src, this.xh, this.xw);
},
_navigateByKey: function(increment, typeCount){
// summary:
// This is the callback for typematic.
// It changes the focus and the highlighed color.
// increment:
// How much the key is navigated.
// typeCount:
// How many times typematic has fired.
// typecount == -1 means the key is released.
if(typeCount == -1){ return; }
var newFocusIndex = this._currentFocus + increment;
if(newFocusIndex < this._cellNodes.length && newFocusIndex > -1)
{
var focusNode = this._cellNodes[newFocusIndex];
focusNode.focus();
}
}
});
});
Update
this.connect(this.btnUpNode, "onclick", "DoUpload");
to be
this.connect(this.btnUpNode, "onClick", "DoUpload");
onclick is a dom event, onClick is a dijit event. Since you are using a dijit button you want to use the latter.