Accessing outer scope from jQuery.each() function - javascript

I want to iterate over all elements of "shift" and update an outer array called new_requests, how do i do this ?, currently i get an undefined error on the line thats supposed to update the array. thanks.
$scope.save = function(){
var new_requests = [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]];
$("shift").each(function(){
var day = $("this").attr("day");
var shift = $("this").attr("shift");
var status = $("this").attr("status");
new_requests[day][shift]=status;
})
console.log(new_requests);
}

Assuming shift is a collection of elements with day, shift and status attributes, use:
$.each($(shift), function() {
var day = $(this).attr("day");
var shift = $(this).attr("shift");
var status = $(this).attr("status");
new_requests[day][shift]=status;
});
Note $(shift) instead of $("shift") and $(this) instead of $("this").

Related

Updating only some of object

I have a table in my database that I would like to be able to change some of the sections and keep the other functions as they were however it is updating the table so that the two are changed but the other 3 become empty. is there any way to change this?
$(function Tuesday(){
// CREATE A REFERENCE TO FIREBASE
var dateTuesdayRef = new Firebase('https://shiftsapp.firebaseio.com/roster');
// REGISTER DOM ELEMENTS
var date2Field = $('#date2Input');
var emp1put2Field = $('#emp1Input2');
var emp2put2Field = $('#emp2Input2');
var emp3put2Field = $('#emp3Input2');
var emp4put2Field = $('#emp4Input2');
var emp5put2Field = $('#emp5Input2');
var enter2Field = $('#enter2');
// LISTEN FOR KEYPRESS EVENT
enter2Field.keypress(function (e) {
if (e.keyCode == 13) {
//FIELD VALUES
var dateTuesday = date2Field.val();
var emp1put2 = emp1put2Field.val();
var emp2put2 = emp2put2Field.val();
var emp3put2 = emp3put2Field.val();
var emp4put2 = emp4put2Field.val();
var emp5put2 = emp5put2Field.val();
var enter2 = enter2Field.val();
//SAVE DATA TO FIREBASE AND EMPTY FIELD
var obj2 = {};
obj2[dateTuesday] = {
emp1:emp1put2,
emp2:emp2put2,
emp3:emp3put2,
emp4:emp4put2,
emp5:emp5put2
}
dateTuesdayRef.child(dateTuesday).set({emp1:emp1put2,
emp2:emp2put2,
emp3:emp3put2,
emp4:emp4put2,
emp5:emp5put2});
enter2Field.val('');
}
});
});
Get the values for the things you want to stay the same from your server, and feed them back when you set the object. You could also use a custom function to autofill undefined values like I have suggested.
From the table at the top of the Firebase guide on saving data:
set( ): Write or replace data to a defined path, like messages/users/
update( ): Update some of the keys for a defined path without replacing all of the data
So if you call update() instead of replace, it will only change the values of the properties you pass in and leave other values unmodified.

Adding Objects to JS Array

I am trying to create an array of objects that contain two pieces of information relating to an order:
Product Stock Code
Product Quantity
Currently I am doing it like this:
$(".orderBtn").click(function(event){
//Show the order Box
$(".order-alert").show();
event.preventDefault();
//Create the Array
var productArray = [];
//Get reference to the product clicked
var stockCode = $(this).closest('li').find('.stock_code').html();
//Get reference to the quantity selected
var quantity = $(this).closest('li').find('.order_amount').val();
var key = "stockCode";
var obj = {
'stockCode' : stockCode,
'quantity' : quantity
};
productArray.push(obj);
$.cookie('order_cookie', JSON.stringify(productArray), { expires: 1, path: '/' });
console.log(productArray);
if(quantity == 0){
console.log("Quantity must be greater than 0")
}
I would expect that each time the order button is clicked that the new object would be added to the array of existing objects but instead It just outputs the array with 1 object, the object I've just added.
Is there something I am missing?
Move your array declaration outside of the function into the global scope.
What happens in your case is that each time you call the function a new array is created(function scope) and therefore only one result is produced.
Read this about scopes\hoistings.
var productArray = [];
$(".orderBtn").click(function(event){
//Show the order Box
$(".order-alert").show();
event.preventDefault();
//Create the Array
//Get reference to the product clicked
var stockCode = $(this).closest('li').find('.stock_code').html();
//Get reference to the quantity selected
var quantity = $(this).closest('li').find('.order_amount').val();
var key = "stockCode";
var obj = {
'stockCode' : stockCode,
'quantity' : quantity
};
productArray.push(obj);
$.cookie('order_cookie', JSON.stringify(productArray), { expires: 1, path: '/' });
console.log(productArray);
if(quantity == 0){
console.log("Quantity must be greater than 0")
}
declare as global variable
var productArray = [];
$(".orderBtn").click(function(event){
// do here
//productArray.push("anyObject");
});
You are recreating / overwriting the productArray every time the button is clicked. Try moving the var productArray = [] to outside of the click handler
Not so, because your
var productArray = [];
is within the function that sets the cookie, so it's getting defined afresh then having one element added each time the function is called.
You'd need to define productArray outside of the function (as a global variable?) so that it retains its previous value, and new objects are added to it
With var productArray = []; you're declaring a new array on every click. Move that line outside the click handler and the code should start working.

Changing the selected object in Javascript

What I am trying to do is rewrite content on the page depending on which object I have selected. I have some objects like so:
function floorPlan(name,rev,sqft,bedrm,bthrm) {
this.name = name;
this.rev = rev;
this.sqft = sqft;
this.bedrm = bedrm;
this.bthrm = bthrm;
}
// 1BR Plans
var a1 = new floorPlan('A1',false,557,1,1);
var a2 = new floorPlan('A2',false,652,1,1);
var a3 = new floorPlan('A3',false,654,1,1);
var a4 = new floorPlan('A4',false,705,1,1);
var a5 = new floorPlan('A5',false,788,1,1);
// The Selected plan
var currentPlan = floorPlan.a1;
I am having the user control this via a .click() function in a menu:
$('.sideNav li').click(function() {
// Define the currentPlan
var current = $(this).attr('id');
var currentPlan = floorPlan.current;
});
The problem is that currentPlan keeps coming back as undefined and I have no idea why. Should I be defining currentPlan differently? I can't seem to find any resources to help me find the answer.
UPDATED:
I switched out a few parts per your suggestions:
// The Selected plan
var currentPlan = a1;
and....
// Define the currentPlan
var current = $(this).attr('id');
currentPlan = current;
However, everything is still returning undefined in the click function (not initially though).
First of all $('this') should be $(this)
Secondly you're trying to use a read ID from your LI as a variable name. That doesn't work. If you store your plans in an array you can use the ID to search in that array:
var plans=Array();
plans["a1"]=new floorPlan('A1',false,557,1,1);
plans["a2"]=new floorPlan('A2',false,652,1,1);
Then your jQuery code should be altered to this:
$('.sideNav li').click(function() {
// Define the currentPlan
var current = $(this).attr('id');
var currentPlan = plans[current];
alert(currentPlan);
});
I created a JSFiddle for this. Is this what you were looking for?
Use as floorPlan.currentPlan = a1;
instead of var currentPlan = floorPlan.a1;
Please create a plunker and will correct if any issue.
I spot two errors.
When you write var inside a function, that variable is only accessible with that function. Right now you are creating a new variable in your anonymous function that is "hiding" the global variable with the same name.
So, first remove the var keyword from the assignment in the anonymous function (the one you call on "click").
Secondly I think you mean to assign floorPlan[current].
The final line should read:
currentPlan = floorPlan[current];

Losing scope when using array.concat() and .slice() together on jquery object list

I think the code will explain it, but I'm trying to slice a jquery object list into an array and then concatenate them onto another array, multiple times. Anyways in the .each function i am getting elements in the lis variable, but when I try to slice and concat them onto the listItemArray, it isn't working. I assume I'm losing scope or there is some binding issue or something, but I can't figure out what it is. Thanks for the help. Also I know there is a jquery.slice method but I wanted to keep it vanilla if possible.
var updateSection7 = function(desired) {
var section = $('#' + _me.UUID + ' .section7yAxis');
var showedList = section.find('ul:not(:hidden)');
var listItemArray = [];
var _slice = Array.prototype.slice;
showedList.each(function(ind,el){
var lis = $(el).find('.control-group');
if(lis.length>1){
listItemArray.concat(_slice.call(lis));
}
});
}
UPDATED: Here I included both the push and concat varieties of solving the problem and did away with some wasted cpu time per requests.
var updateSection7 = function(desired) {
var lis = $('#' + _me.UUID + ' .section7yAxis ul:not(:hidden) .control-group');
var listItemArray = [];
var concatTester = [];
var _slice = Array.prototype.slice;
var _push = Array.prototype.push;
//these end up doing the same thing
_push.apply(listItemArray, _slice.call(lis));
concatTester = concatTester.concat(_slice.call(lis));
}
concat doesn't mutate the original array. It returns the new array.
Try this:
listItemArray = listItemArray.concat(_slice.call(lis));

Empy array values are created when adding to array

I have the below code:
var changes = new Array();
$(".item_prices").on("blur", function(){
var item_id = $(this).attr("id");
var item_price = $(this).html();
changes[item_id] = item_price;
});
Every time a new value is entered, I want to save the item's ID as the key and its price as the value. If I save items with IDs 4 and 6 and prices 1.99 and 2.99, respectively, I get the following array:
{,,,,1.99,,2.99}
How do I add to the array without incurring empty values?
Use object, not Array:
var changes = {};
The rest is the same.
Key-value should always be saved in an object.
Since you're using jQuery, here is another answer to an unasked question,
Use native javascript functions when it's possible and simple, specially when it's even simpler:
var item_id = $(this).attr("id");
var item_price = $(this).html();
Can and should be:
var item_id = this.id
var item_price = this.innerHTML;
You don't want an array, a simple object will form a collection of key value pairs for you:
var changes = {};
If / when the time comes to enumerate these changes:
for (var name in changes) {
if (changes.hasOwnProperty(name)) {
var value = changes[name];
...
}
}
Arrays are a special case of objects, whose elements have consecutive integer keys. You don't have consecutive keys, so Array is "filling the gaps" for you.
Use a barebones Object instead:
var changes = {};

Categories