Updating only some of object - javascript

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.

Related

Dynamically append Javascript variable to URL

Im attempting to produce a dynamic url containing multiple javascript variables but i only want to include them if they contain information.
These variables are essentially filters which will be used to Select from a MYSQL databse so they take form of "column=value".
The url i am trying to produce will need to be in the format of
page.php?column1=value1&column2=value2.... etc.
i am struggling to work out how to include only the variables that contain info and then how to insert the required "&" between each variable.
The current code is below and currently contains just the two variabls but the aim is to have as many as 5.
var jsedibility = "";
function chosenEdibility(choice){
jsedibility = choice;
}
var jsfrequency = "";
function chosenFrequency(choice2){
jsfrequency = choice2;
}
function setFilters(){
window.location='search.php?' + jsedibility+"&"+jsfrequency;
}
i am then using "onClick=setFilters()" assigned to a button to load the relevant page.
How can i set this up so that the URL is produced dynamically, only containing the variables that have data in them and also to add the required "&" between each variable.
Massively appreciate any help :)
I would make an array of the variables then use join().
var filters = [];
Use an if statement to check that they are not empty strings.
if (jsedibility != ""){ filters.push(jsedibility) }
var filtersString = filters.join('&');
Then in your setFilters(),
window.location.assign('./' + filtersString)
This works with any number of variables.
// mockup data object
const obj = {
jsedibility: '',
jsfrequency: '',
jsvar1: '',
jsvar2: '',
jsvar3: ''
}
// setting object values
function setObjVal(obj) {
obj.jsedibility = 'choice1'
obj.jsfrequency = 'choice2'
}
// creating the filter string
function setFilters(obj) {
return Object.values(obj).filter(val => val !== '').join('&')
}
document.getElementById('setFilters').addEventListener('click', function(e) {
setObjVal(obj)
console.log(setFilters(obj))
})
<button id="setFilters">Filters</button>
Or another with an array:
// mockup data
const choice = 'ch1'
const choice2 = 'ch2'
const array = []
var jsedibility = "";
function chosenEdibility(choice) {
jsedibility = choice;
}
var jsfrequency = "";
function chosenFrequency(choice2) {
jsfrequency = choice2;
}
// showing that it can be filtered out
var noValue = "";
function chosenNoValue(choice3) {
noValue = choice3;
}
chosenEdibility(choice)
chosenNoValue('') // empty value
chosenFrequency(choice2)
document.getElementById('setFilters').addEventListener('click', function(e) {
array.push(jsedibility)
array.push(noValue)
array.push(jsfrequency)
// string filtered for not empty values
const filterString = array.filter(el => el !== '').join('&')
console.log(filterString)
})
<button id="setFilters">Filters</button>

Can I gather multiple variables from text boxes in a quicker fashion?

In code.org, I'm trying to gather data from text boxes where they can enter numbers. I want to assign the numbers entered into the text boxes into different variables.
Right now, I am individually grabbing each variable by itself.
I am currently creating variables at the beginning of my code like this.
var player1 = "player1";
var player2 = "player2";
var player3 = "player3";
var player4 = "player4";
var player5 = "player5";
Then after I used the onEvent handler function, I grab each of the numbers individually using the getText function.
onEvent("team2Button", "click", function () {
player1 = getText("player1");
player2 = getText("player2");
player3 = getText("player3");
player4 = getText("player4");
player5 = getText("player5");
});
Since I have many around 30 sets of data to collect, is there a quicker way to assign these values into a variable?
You can use an Object:
const players = {};
for(let i = 1; i <= 30; i++) {
players[`player${i}`] = `player${i}`
}
onEvent('button', 'click', function(){
for(let key in players){
players[key] = getText(key)
}
})
You could use the "design" tab to create a text input, and then write some code to add a new entry to a list every time you type something in and press enter:
var players = [];
onEvent("text_input1", "change", function(event) {
var name = getText("text_input1");
appendItem(players, name);
setText("text_input1", '');
console.log("added player: " + name);
});
If you want to keep this text input separate from the rest of your app, you could put it on a different screen. For example: https://studio.code.org/projects/applab/3vINC-jX6LHkiARJCoCmUQ

Can bind $scope but can't access array unless add Alert()

I am using the SharePoint JavaScript Object Model within an Angular controller to retrieve data from the Taxonomy (term store). By using $scope.apply, I am able to bind the array to scope and use the values in a dropdown since SharePoint's JavaScript Object Model is not a normal Angular function understood by scope. This works as intended.
Now I need to set the value of the field to the current value stored in the database. This works with the following for dropdown/choice based fields where I retrieve the index of the item via a search of the array. Example:
var currentCategoryIndex = $scope.categoryValues.map(function (e) { return e.value; }).indexOf(currentCategoryValue);
$scope.vm.selectedCategory = $scope.categoryValues[currentCategoryIndex];
However, I can't access my array within the controller to check for the index (see code below). It does, however, bind the $scope for use in the dropdown via the $scope.$apply.
Something else really odd is if I add an alert, it will start working, like it somehow forces scope back. But using an alert on page load every time just to get the array working is not realistic.
I need to access the array so I can compare against it and get the index so I can set the field value to the correct item currently stored in the database.
Here is the function in my controller. Note that I need to run a sub function to get all the values. This works to create the $scope.termsArray binding that I use in my dropdown, it is the setting of $scope.vm.selectedCategory where the issue is occurring:
var termsArray = [];
// Query Term Store and get terms for use in Managed Metadata picker stored in an array named "termsArray".
function execOperation() {
// Current Context
var context = SP.ClientContext.get_current();
// Current Taxonomy Session
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
// Term Stores
var termStores = taxSession.get_termStores();
// Name of the Term Store from which to get the Terms. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
var termStore = termStores.getByName("Taxonomy1234");
// GUID of Term Set from which to get the Terms
var termSet = termStore.getTermSet("1234");
var terms = termSet.getAllTerms();
context.load(terms);
context.executeQueryAsync(function () {
var termEnumerator = terms.getEnumerator();
while (termEnumerator.moveNext()) {
var currentTerm = termEnumerator.get_current();
var guid = currentTerm.get_id();
var guidString = guid.toString();
var termLabel = currentTerm.get_name();
// Get labels (synonyms) for each term and push values to array
getLabels(guid, guidString, termLabel);
}
// Set $scope to terms array
$scope.$apply(function () {
$scope.termsArray = termsArray;
console.log($scope.termsArray); // DOES NOT LOG ARRAY
});
var currentFacilityIndex = termsArray.map(function (e) { return e.termGUID; }).indexOf(currentFacilityGUID);
console.log(currentFacilityIndex);
$scope.term.selected = termsArray[currentFacilityIndex];
}, function (sender, args) {
console.log(args.get_message());
});
// Get labels (synonyms) for each term and push values to array
function getLabels(termguid, guidString, termLabel) {
var clientContext = SP.ClientContext.get_current();
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(clientContext);
var termStores = taxSession.get_termStores();
// The name of the term store. Note, that if you receive the following error "Specified argument was out of the range of valid values. Parameter name: index", you may need to check the term store name under Term Store Management to ensure it was not changed by Microsoft
var termStore = termStores.getByName("Taxonomy1234");
// GUID of Term Set from which to get the Terms
var termSet = termStore.getTermSet("1234");
var term = termSet.getTerm(termguid);
var labelColl = term.getAllLabels(1033);
clientContext.load(labelColl);
clientContext.executeQueryAsync(function () {
var labelEnumerator = labelColl.getEnumerator();
var synonyms = "";
while (labelEnumerator.moveNext()) {
var label = labelEnumerator.get_current();
var value = label.get_value();
synonyms += value + " | ";
}
termsArray.push({
termName: termLabel,
termGUID: guidString,
termSynonyms: synonyms
});
}, function (sender, args) {
console.log(args.get_message());
});
}
};
// Execute function
execOperation();
UPDATE: I tried setting the $scope.termsArray = []; per the suggestion below, but it didn't work. What is really odd is that if I have an alert as follows, it somehow forces the console to log/grants me access to the array in the controller.
$scope.$apply(function () {
$scope.termsArray = termsArray;
alert("hey");
console.log($scope.termsArray);
});
I found a bit hard to follow your code.
My first guess would be to instantiate the array with empty value before anything else.
$scope.termsArray = [];
This trick tells Angular that this property exists and will exist at later stage.

storing forms and their elements values in a variable

I have a single page web app.
For speed, I store each 'page' in the JS.
I have a problem which happens when there is a form on a page. If you fill in the form, and then store it in a js variable, and then retrieve it, the forms values have disappeared?
I use functions like:
var pages_html = {};
var $page = $('#some-page');
store_page($page);
$page.remove();
//some stuff on another page
var $retrieved_page = get_page('some-page');
console.log($retrieved_page.find('#some-input').val())
//consoles log is always blank / ''
function store_page(page){
var page_id = $(page).attr('id');
pages_html[page_id] = $(page);
}
function get_page(page_id){
var page = pages_html[page_id];
return $(page);
}
Everything else seems to work, i can store and retrieve pages as i wish, its just any values of form elements are lost. How can I work around this?
You cannot store it like that. Instead store it as serialized array. which you can then fill it back when needed. serializeArray returns Array of Objects which have name and value
var values = {};
function store_page(page){
var page_id = $(page).attr('id');
pages_html[page_id] = $(page);
values[page_id] = $(page).find("form").serializeArray(); // serialize it
}
function get_page(page_id){
var page = pages_html[page_id];
values[page_id].forEach(function(obj){
page.find('[name=' + obj.name + ']').val(obj.value) // add it again
});
return page; // and then return
}

How to add a variable to a javascript/jQuery object?

Well, the problem is quite simple. I got an object of parsed table rows. Code for it is this:
var erg = [];
$("tr").each(function (index) {
var row = {};
var test = $(this).children();
row['column1'] = test[0].textContent;
row['column2'] = test[1].textContent;
row['column3'] = test[2].textContent;
row['column4'] = test[3].textContent;
row['column5'] = test[4].textContent;
row['column6'] = test[5].textContent;
row['column7'] = test[6].textContent;
erg.push(row);
});
And I wanna pass a variable var my_variable="blabla" to it without ruining the structure of the object. So how could i bring that object into a structure like this?:
Object{my_variable="my_variable_value"}, Object{my_table=[Object{...}, Object{...}]} //all the objects of the table
$.extend({}, erg, my_variable); only messed my object up.
I want it in that structure so i can pass it as json to my php script and filter my variable easily. Any tips, links, code snippets? :)
I'm not sure at which point you want to add that, but you may simply wrap your array with another object, and add your property to that same object.
This is basically what Florent's answer does, but using an object literal instead of a "class" and prototype:
// (your current code)
var wrapper = {
my_variable: 'something',
my_table: erg
};
You can define a class and add the needed variables to its prototype.
First you need a little utility to do that:
function createSharedStruct() {
// Define a shared structure
var Struct = function() {};
// Define a method to define a shared variable
Struct.share = function(variable, value) {
Struct.prototype[variable] = value;
};
return Struct;
}
And then, update your code:
// Create the shared structure
var rowClass = createSharedStruct();
// Register your shared variables
rowClass.share('my_variable', 'my_variable_value');
var erg = [];
$("tr").each(function (index) {
var test = $(this).children();
// Create a new row
var row = new rowClass();
row['column1'] = test[0].textContent;
row['column2'] = test[1].textContent;
row['column3'] = test[2].textContent;
row['column4'] = test[3].textContent;
row['column5'] = test[4].textContent;
row['column6'] = test[5].textContent;
row['column7'] = test[6].textContent;
erg.push(row);
});
// No matter when you share a variable, it will be defined among
// all instances of the same struct.
rowClass.share('my_other_var', 42);
Now you can access shared variables:
console.log(erg[0].my_other_variable); // 42
console.log(erg[1].my_other_variable); // 42
Demo available on JSFiddle.

Categories