javascript error only in IE - javascript

I get this error, only in IE:
Object doesn't support this property or method
Line: 56
Sign: 5
Code: 0
Javascript code:
function recalcTotalPrice(item) {
values = $("input", item).serialize();
$.post( url,
values,
function (data,textStatus, jqXHR) {
variant_wrapper = $(item).parents(".variant");
$(".price", variant_wrapper).html(data.total_price);
56: updateProductPrice(item);
})
};
function updateProductPrice(item) {
wrapper = $(item).parents('.advertising_product');
$(".total_price", wrapper).html(sum($(".price", wrapper).map(function() {return parseFloat($(this).html())}).toArray()));
};
Anyone?
EDIT 1:
Here is the rendered HTML code that triggers the javascript:
<li>
<label class="month" for="month">Mar</label>
<div class="week ">
<input id="386_1_10" name="book[]weeks[]" style="display: none;" type="checkbox" value="1|10" />
<label for="386_1_10">10</label>
</div>
<div class="week ">
<input id="386_1_11" name="book[]weeks[]" style="display: none;" type="checkbox" value="1|11" />
<label for="386_1_11">11</label>
</div>
<div class="week ">
<input id="386_1_12" name="book[]weeks[]" style="display: none;" type="checkbox" value="1|12" />
<label for="386_1_12">12</label>
</div>
<div class="week ">
<input id="386_1_13" name="book[]weeks[]" style="display: none;" type="checkbox" value="1|13" />
<label for="386_1_13">13</label>
</div>
</li>
<script>
$('#item_386.week_picker_wrapper').weekPicker(
{
url: '/products/100/items/386/calc_total_price'
}
);
</script>
When the Checkbox is clicked the javascript is called.
Here is the full javascript code:
jQuery.fn.weekPicker = function(options) {
var self = this;
var week_picker = new WeekPicker(options, self);
}
jQuery.fn.weekLocker = function() {
var self = this;
var week_picker = new WeekLocker(self);
};
WeekPicker = function(options, selector) {
var url = options.url;
var yearPos = 0;
$("a.prev_year", selector).click(function() {
if (yearPos > 0) {
$(".year", selector).css("margin-left", --yearPos * -55)
$(".week_picker", selector).css("margin-left", yearPos * -185)
}
return false;
})
$("a.next_year", selector).click(function() {
if (yearPos < 2) {
$(".year", selector).css("margin-left", ++yearPos * -55)
$(".week_picker", selector).css("margin-left", yearPos * -185)
}
return false;
})
$(".disabled input[type='checkbox'], .busy input[type='checkbox'], .locked input[type='checkbox']", selector).click(function () {
return false;
})
$("input[type='checkbox']", selector).change(function() {
recalcTotalPrice(selector);
});
function getValues(selection) {
return selection.map(function() {return $(this).html()}).toArray().join(",")
}
function recalcTotalPrice(item) {
values = $("input", item).serialize();
$.post( url,
values,
function (data,textStatus, jqXHR) {
variant_wrapper = $(item).parents(".variant");
$(".price", variant_wrapper).html(data.total_price);
updateProductPrice(item);
})
};
function updateProductPrice(item) {
var wrapper = $(item).parents('.advertising_product');
$(".total_price", wrapper).html(sum($(".price", wrapper).map(function() {return parseFloat($(this).html())}).toArray()));
};
function sum(arr) {
for(var s = 0, i = arr.length; i; s += arr[--i]);
return s;
};
recalcTotalPrice(selector);
};
EDIT 2:
I got rid of the nasty errors, so now I "only" have one more problem.
This function, wont fire in IE7, IE8
$("input[type='checkbox']", selector).change(function() {
recalcTotalPrice(selector);
});
I suspect the it is the "change" that dosent work in IE. I have found this http://www.sitepoint.com/forums/showthread.php?626340-jQuery-change()-event-in-IE-not-triggering-properly-with-checkbox
But I don't know how to implement it into my code.

I think it's simply that you forgot var !
var wrapper = $(item).parents('.advertising_product');

Related

Read html tags as a tree

I'm trying to read HTML elements using jQuery and store it's contents in object like a tree.
for example if I have this:
<div class="box">
<input type="text" data-type="name">
<div class="box">
<input type="email" data-type="email">
<input type="text" data-type="another_input">
<div class="box">
<!-- ETC -->
</div>
</div>
</div>
then the javascript object would be like:
{
box: {
name: "input value",
box: {
email: "input value",
another_input: "input_value",
box: {
// ETC...
}
}
}
}
my current cdoe:
var items = [];
$( ".root > .box" ).each( function (){
$(this).find( "*" ).each( function() {
if( haveChilds( $(this) ) ) {
// recursing
} else {
items[ $(this).data("type") ] = $(this).val();
}
});
});
function haveChilds( $element ) {
if( $element.hasClass( "box" ) )
return true;
}
is there's any easy way to do this in jQuery or Javascript?
Thanks in advance..
You can recurse over the dom tree and children nodes to build an object like this. I am not sure if this is a good idea. You may want to expand on what you actually want, as an end goal, so we can give a proper answer.
function buildDomMap(target) {
var node = {};
for (var i = 0; i < target.children.length; i += 1) {
var child = target.children[i];
var childName = child.getAttribute("data-type") || child.className;
if (child instanceof HTMLInputElement) {
node[childName] = child.value;
} else /* if (/\bbox\b/.test(child.className)) /* only crawl box? */ {
node[childName] = buildDomMap(child)
}
}
return node;
}
function buildAndLog() {
var startingNode = document.getElementsByClassName("box")[0];
console.log(JSON.stringify(buildDomMap(startingNode), null, 2))
}
<div class="box">
<input type="text" data-type="name">
<div class="box">
<input type="email" data-type="email">
<input type="text" data-type="another_input">
<div class="box">
<!-- ETC -->
</div>
</div>
</div>
<button onclick="buildAndLog()">Get data</button>

How to return value from my jquery function

So I have a control (textbox) being created for each row in my grid view. (c#.net)
So for each of the text boxes, I want to find the current active element and return its id.
it kind of works, but I am having some issues.
I know item.addEventListener does not return a value.
Any ideas on how i can return the value after calling the addListener() function?
var controls = {
txt: null,
};
var selectedTextArea;
var items = document.getElementsByClassName("textboxnew");
for (var i = 0; i < items.length; i++) {
controls = addListener(items[i], controls);
alert(controls.txt); ///GET ERROR HERE
}
function addListener(item, ctrls) {
selectedTextArea = document.activeElement;
ctrls.txt = selectedTextArea.name.toString();
item.addEventListener("click", function () {
selectedTextArea = document.activeElement;
ctrls.txt = selectedTextArea.name.toString();
alert(ctrls);
});
return ctrls; //VALUE NOT RETURNED ???
}
You can use jQuery.Callbacks() to define a callback function that can be fired with parameters passed.
var callbacks = jQuery.Callbacks();
function active(id) {
alert(id)
}
callbacks.add(active);
$("input").on("click", function() {
callbacks.fire(document.activeElement.id)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<input id="1" autofocus tabindex="1">
<input id="2" tabindex="2">
<input id="3" tabindex="3">

Angular ng-model not updating after typing into number input

So basically I'm creating a simple app with two controllers. ControllerA button increments ControllerB number input and vicer versa.
The problem is that $scope.total is not updating after typing into number input manually, and I don't know what would be the best way to achieve this.
HTML
<div ng-app="tabsApp">
<div id="tabOne" class="tabcontent">
<div ng-controller="tabOneController as vm">
<input type="button" value="increment value in tab 2" ng-click="vm.sumar()"/>
<input type="number" ng-model="vm.totalB.value">
</div>
</div>
<div id="tabTwo" class="tabcontent">
<div ng-controller="tabTwoController as vm">
<input type="button" value="increment value in tab 1" ng-click="vm.sumar()"/>
<input type="number" ng-model="vm.total.value">
</div>
</div>
</div>
JS
var app = angular.module('tabsApp', []);
app.controller("tabOneController", controllerA);
app.controller("tabTwoController", controllerB);
app.service('myData', function() {
var data = {
value: 0
}, dataB = {
value: 0
};
this.addItem = function (value) {
data.value = value;
}
this.getItem = function() {
return data;
}
this.addItemB = function (value) {
dataB.value = value;
}
this.getItemB = function() {
return dataB;
}
});
function controllerA(myData){
var scope = this;
scope.total = 0;
scope.sumar = function(){
scope.total++;
myData.addItem(scope.total);
}
scope.totalB = myData.getItemB();
}
function controllerB(myData){
var scope = this;
scope.totalB = 0;
scope.sumar = function(){
scope.totalB = myData
scope.totalB++;
myData.addItemB(scope.totalB);
}
scope.total = myData.getItem();
}
Here's a working example based on your code : Plunker
function controllerA(myData){
var scope = this;
scope.total = 0;
scope.sumar = function(){
scope.total = myData.getItem().value; // added this line
scope.total++;
myData.addItem(scope.total);
}
scope.totalB = myData.getItemB();
}
function controllerB(myData){
var scope = this;
scope.totalB = 0;
scope.sumar = function(){
scope.totalB = myData.getItemB().value; // modified this line
scope.totalB++;
myData.addItemB(scope.totalB);
}
scope.total = myData.getItem();
}
scope.totalB = myData.getItemB(); // first controller
scope.total = myData.getItem(); // second controller
These will be called just once when controller is loaded. Place them inside the function sumar
Use vm.total and vm.totalB instead of vm.total.value and vm.totalB.value in html
You could try implementing required ng-change="controller.functionThatIncrementsValues" in your html.
Would something like this help:
HTML
<div ng-app="tabsApp" ng-controller="tabController as vm">
<div id="tabOne" class="tabcontent">
<div>
<input type="button" ng-click="vm.one++" />
<input type="number" ng-model="vm.two">
</div>
</div>
<div id="tabTwo" class="tabcontent">
<div>
<input type="button" ng-click="vm.two++" />
<input type="number" ng-model="vm.one">
</div>
</div>
<p>Total (method 1): {{vm.one + vm.two}}</p>
<p>Total (method 2): {{ total(vm.one, vm.two) }}</p>
</div>
JS
var app = angular.module('tabsApp', []);
app.controller("tabController", function() {
this.one = 0;
this.two = 0;
this.total = function(one, two) {
return one + two;
}
})
Unless you have a specific need for two controllers and a service I would just put this all in one controller. At the moment what you have is massive overkill.

Blur function not being called

I have the following code for sharing an article by email
function internalLabelBlur(elm) {
if (!elm.value) {
elm.value = elm.defaultValue;
}
if (elm.value == elm.defaultValue) {
elm.className = elm.className.replace("internal-label-emph", "internal-label");
}
} // function internalLabelBlur(elm)
function internalLabelFocus(elm) {
if (elm.value == elm.defaultValue) {
elm.value = "";
}
elm.className = elm.className.replace("internal-label", "internal-label-emph");
} // function internalLabelFocus(elm)
function z_onclick() {
return false;
}
Markup:
<div id="emailErrEmailAddressArrow" class="errorarrow" style="visibility:hidden;">
<img src="~/Content/Images/error_arrow_signup.png" alt="sign up error arrow">
</div>
<input id="txtEmailAddress" name="txtEmailAddress" class="internal-label inputbox"
onfocus="javascript:internalLabelFocus(this);"
onblur="javascript:internalLabelBlur(this);"
onclick="return z_onclick()" type="text" value="E-mail address*" />
The problem is the onblur function not being called. Can anyone help me as to why?

Click event firing multiple times

I am learning to write a plugin for myself, but I got something odd in the code. I have a reset button, and when I click it, it runs as times as the number of input elements I have.
My code: jsbin, jsfiddle
HTML:
<div id="container">
<div id="createCSVWrap">
<fieldset>
<legend> Create the CVS File </legend>
<div class="dateWrap">
<label> 开始时间: </label>
<div style="float:right">
<input id="startTime" name="startTime" type="text" value="13:37:06" />
</div>
</div>
</fieldset>
</div>
<input id="f" name="fck" value="18:27:56" />
<input class="tt" name="tt" value="02:07:56" />
<input name="ok" class="ok" value="08:07:56" />
</div>
Javascript
$(document).ready(function() {
$('#startTime').timePicker();
$('#f').timePicker();
$('.tt').timePicker();
$('.ok').timePicker();
});
(function($) {
$.fn.timePicker = function(options) {
var defaults = {
setTimeFocus: 'hour'
}; //,originalTime :''
var options = $.extend(defaults, options);
if ($('#timePicker').length === 0) {
var timePickerBody = '<div id="timePicker" style="display:none;">' + '<div id="setTimeOption">' + ' RESET' + '</div></div>';
$("body").append(timePickerBody);
}
return this.each(function() {
var o = options;
$(this).focus(function() {
_input = $(this); // ONLY put here can change value of each input field
originalTime = '';
//originalTime = {} ;
intial();
});
function intial() {
showSetTime();
setTimePickerPosition();
$('#timeReset ').click(resetTime);
}
function showSetTime() {
$('#timePicker').show();
}
function hiddenSetTime() {
$('#timePicker').hide();
}
function setTimePickerPosition() {
var _inputPosition = _input.offset();
var _timePickerPosition = [_inputPosition.left, _inputPosition.top + _input.height()];
var _timePickerPositionLeft = _timePickerPosition[0],
_timePickerPositionTop = _timePickerPosition[1];
$('#timePicker').css({
'left': _timePickerPositionLeft + 'px',
'top': _timePickerPositionTop + 'px'
});
}
time = 1;
function resetTime(event) {
event.preventDefault();
time++;
alert(time)
}
$(this).click(function(e) {
e.stopPropagation();
});
$('#timePicker').click(function(e) {
e.stopPropagation();
});
$(document).click(function() {
hiddenSetTime();
});
});
// ending return this
};
})(jQuery);
CSS:
#timePicker
{
position:absolute;
width:185px;
padding:10px;
margin-top:5px;
background:#F3F3F3;
border:1px solid #999;
}
I think I see the problem here. It's to do with this bit of code:
$(this).focus(function() {
_input = $(this);
originalTime = '';
intial();
});
function intial() {
showSetTime();
setTimePickerPosition();
$('#timeReset').click(resetTime);
}
This basically means that every time the user focuses onto the textbox another click handler will get attached to the "Reset" button, thus the same event firing multiple times.
What you need to do is the unbind the old event and reattach a new one, with the unbind event.
$('#timeReset').unbind('click').click(resetTime);
See it working here: http://www.jsfiddle.net/Sc6QB/1/

Categories

Resources