chosen-select mutliple select update from an array - javascript

I'm using the chosen plugin for a multiple select. I want to retrieve the customer pre-selected values from the database and display them in the multiple select when i return the rest of the data.
The following code works fine:
$('.chosen-select').val(["Test1", "Test2"]).trigger('chosen:updated');
However when I try and put a variable in there like below, it doesn't populate the values.
$('.chosen-select').val([res]).trigger('chosen:updated');
I've pulled the data out and I then loop through the array and store it in a variable. I've checked the contents of the res variable and it's correct, so now I'd like to reference it within the square brackets but it doesn't work, and it doesn't throw any errors. Any help would be much appreciated!
var i;
var res = "";
for (i = 0; i < array.length; i++) {
array[i] = $.trim(array[i]);
var buildValue2 = '"' + array[i] + '", ';
if (i == array.length - 1) {
/* this is the last one so no comma*/
buildValue2 = '"' + array[i] + '"';
}
res = res.concat(buildValue2);
}
alert(res);
$('.chosen-select').val([res]).trigger('chosen:updated');

Related

Possible to display an Array with for loop and InnerHTML?

I just wanted to display my Array inside of either an div or a heading.
The code i posted down below only displays the last part of the "List".
When i tried to use: document.write instead, everything worked fine.
Is there any special trick to display the list the same way document.write does using my Code below?
var Users = ["Till", "Didi", "Klausi", "Heinz"];
for (var i = 0; i < Users.length; i++) {
document.querySelector("div").innerHTML = Users[i] + " is always on my page " + "<br>";
}
Build the whole HTML first by iterating on the array and concatenating strings. And then set it as innerHTML of the div.
var Users = ["Till", "Didi", "Klausi", "Heinz"];
var _html = "";
for (var i = 0; i < Users.length; i++) {
_html += Users[i] + " is always on my page " + "<br>";
}
document.querySelector("div").innerHTML = _html;
<div></div>
Every time the loop runs it inserts the current iterable item into the HTML, replacing the one previous. So add a variable outside of the loop and append to it using var x += User[i].
var separator = ' is always on my page<br>';
var html = Users.join(separator) + separator;
document.querySelector("div").innerHTML = html;
// writes
// "Till is always on my page<br>Didi is always on my page<br>Klausi is always on my page<br>Heinz is always on my page<br>"

Is it possible to use a value from within a 'for' loop outside of the actual loop cycle?

I have a for loop that cycles through my array and prints to the console each value that meets a certain condition. I would like to take these values and insert them into variables outside the loop. Is this possible?
for (var i = 0; i < myArray.length; i++) {
if (myArray[i].catType === 'I') {
console.log(myArray[i].location);
}
...
}
I'd like to insert whatever is outputted from the for loop in a tooltip object that sits outside of this for loop.
var header = "<thead>" +
"<tr>" +
"<td class='legend-color-guide'><div style='background-color: " + series.color + ";'></div></td>" +
"<td class='key'><strong>" + <INSERT HERE> + "</strong></td>" +
"</tr>" +
"</thead>";
How can this be done?
Create an array, add the new value each time the condition is meet.
var arr = [];// initialize array
for (var i = 0; i < myArray.length; i++) {
if (myArray[i].catType === 'I') {
console.log(myArray[i].location);
arr.push("Add Whatever Here");// append new value to the array
}
}
This is possible, but you don't (and shouldn't) want to use the output from the console. Instead, you want to append the values to a variable, and then set the header variable. Like: (I've used another example)
var putIn = "";
for (i = 0; i < array.length; i++) {
if (array[i] === x) {
putIn += array[i].property;
console.log(array[i].property);
}
}
var final = "on the left side " + putIn + " on the right side";
As you can see, I've put the values in the string and logged the elements in the array separately. There's no need to use the log values as values to insert into the string.
Define a global variable. Then set that variable in your loop cycle. Or create an array and push each value from your loop into the array, then you can access them from something else.

Pull information from a data file?

I have over 170000 entries of data in data file in this format:
1479661:-1,1,-1,-898,-769,0.00;-1,2,-1,-96,-1402,0.00;-1,3,-1,117,-1397,0.00;-1,4,-1,-4,-2420,0.00;4,5,-1,5570,4395,0.00;4,6,-1,5570,4395,0.00;4,7,-1,5570,4395,0.00;4,8,-1,5570,4395,0.00;4,9,-1,5570,4395,0.00;4,10,-1,5570,4395,0.00;4,11,-1,5570,4395,0.00;4,12,-1,5570,4395,0.00;4,13,-1,5570,4395,0.00;4,14,-1,5570,4395,0.00;-1,15,-1,913,-3533,0.00;4,16,-1,5570,4395,0.00;4,17,-1,5570,4395,0.00;4,18,-1,5570,4395,0.00;4,19,-1,5570,4395,0.00;4,20,-1,5570,4395,0.00;4,21,-1,5570,4395,0.00;4,22,-1,5570,4395,0.00;4,23,-1,5570,4395,0.00;4,24,-1,5570,4395,0.00;4,25,-1,5570,4395,0.00;4,26,-1,5570,4395,0.00;4,27,-1,5570,4395,0.00;4,28,-1,5570,4395,0.00;4,29,-1,5570,4395,0.00;:117,-1397,7,7.00,A,Dead;:
1479662:-1,1,-1,-898,-769,0.00;-1,2,-1,-96,-1402,0.00;-1,3,-1,117,-1392,0.00;-1,4,-1,-6,-2419,0.00;4,5,-1,5570,4395,0.00;4,6,-1,5570,4395,0.00;4,7,-1,5570,4395,0.00;4,8,-1,5570,4395,0.00;4,9,-1,5570,4395,0.00;4,10,-1,5570,4395,0.00;4,11,-1,5570,4395,0.00;4,12,-1,5570,4395,0.00;4,13,-1,5570,4395,0.00;4,14,-1,5570,4395,0.00;-1,15,-1,913,-3533,0.00;4,16,-1,5570,4395,0.00;4,17,-1,5570,4395,0.00;4,18,-1,5570,4395,0.00;4,19,-1,5570,4395,0.00;4,20,-1,5570,4395,0.00;4,21,-1,5570,4395,0.00;4,22,-1,5570,4395,0.00;4,23,-1,5570,4395,0.00;4,24,-1,5570,4395,0.00;4,25,-1,5570,4395,0.00;4,26,-1,5570,4395,0.00;4,27,-1,5570,4395,0.00;4,28,-1,5570,4395,0.00;4,29,-1,5570,4395,0.00;:117,-1392,7,7.07,A,Dead;:
Now each data array starts with a unique id and i was wondering is there a convenient way to push each entry 1479661 then 1479662 every second to an array and assign the values within the unique id into 6 fields that update.
Now I ask if there is a more convenient way as currently I am using this method:
Data comprises of three chunks in a single line
Split the link into chunks
var chunkOne = [1479661];
var chunkTwo = [-1,1,-1,-898,-769,0.00,-1,2,-1,-96,-1402,0.00,-1,3,-1,117,-1397,0.00,-1,4,-1,-4,-2420,0.00,4,5,-1,5570,4395,0.00,4,6,-1,5570,4395,0.00,4,7,-1,5570,4395,0.00,4,8,-1,5570,4395,0.00,4,9,-1,5570,4395,0.00,4,10,-1,5570,4395,0.00,4,11,-1,5570,4395,0.00,4,12,-1,5570,4395,0.00,4,13,-1,5570,4395,0.00,4,14,-1,5570,4395,0.00,-1,15,-1,913,-3533,0.00,4,16,-1,5570,4395,0.00,4,17,-1,5570,4395,0.00,4,18,-1,5570,4395,0.00,4,19,-1,5570,4395,0.00,4,20,-1,5570,4395,0.00,4,21,-1,5570,4395,0.00,4,22,-1,5570,4395,0.00,4,23,-1,5570,4395,0.00,4,24,-1,5570,4395,0.00,4,25,-1,5570,4395,0.00,4,26,-1,5570,4395,0.00,4,27,-1,5570,4395,0.00,4,28,-1,5570,4395,0.00,4,29,-1,5570,4395,0.00];
var chunkThree = [117,-1397,7,7.00,"A","Dead"];
Then get length of each array:
var chunkOneLength = chunkOne.length;
var chunkTwoLength = chunkTwo.length;
var chunkThreeLength = chunkThree.length;
Pick out the nth value in the array depending on the data chunk:
//uniqueID set as first
for (var i = 0; i < chunkOneLength; i = i + 1) {
// useful code would go here
alert("This is the unique ID " + chunkOne[i]);
}
//teamval
for (var i = 0; i < chunkTwoLength; i = i + 6) {
// useful code would go here
alert("This is the teamVal " + chunkTwo[i]);
}
Now the only problem I see with this method, is that the original data array will need to be formatted and separated into chunks every time.
As you have a separator on each section i.e. : you can actually use split to split them up like below and push them into a array and only have to do 2 loops - firstly pushing the split data in a new array and then looping through them and populating the structure.
Please note as long as each chunk of data is separated with : this will work with anything even if you expand the data later. obviously it will not work if you remove the : separator.
example below:
var splitChucks = [];
var chucks = [ "1479661:-1,1,-1,-898,-769,0.00;-1,2,-1,-96,-1402,0.00;-1,3,-1,117,-1397,0.00;-1,4,-1,-4,-2420,0.00;4,5,-1,5570,4395,0.00;4,6,-1,5570,4395,0.00;4,7,-1,5570,4395,0.00;4,8,-1,5570,4395,0.00;4,9,-1,5570,4395,0.00;4,10,-1,5570,4395,0.00;4,11,-1,5570,4395,0.00;4,12,-1,5570,4395,0.00;4,13,-1,5570,4395,0.00;4,14,-1,5570,4395,0.00;-1,15,-1,913,-3533,0.00;4,16,-1,5570,4395,0.00;4,17,-1,5570,4395,0.00;4,18,-1,5570,4395,0.00;4,19,-1,5570,4395,0.00;4,20,-1,5570,4395,0.00;4,21,-1,5570,4395,0.00;4,22,-1,5570,4395,0.00;4,23,-1,5570,4395,0.00;4,24,-1,5570,4395,0.00;4,25,-1,5570,4395,0.00;4,26,-1,5570,4395,0.00;4,27,-1,5570,4395,0.00;4,28,-1,5570,4395,0.00;4,29,-1,5570,4395,0.00;:117,-1397,7,7.00,A,Dead;:", "1479662:-1,1,-1,-898,-769,0.00;-1,2,-1,-96,-1402,0.00;-1,3,-1,117,-1392,0.00;-1,4,-1,-6,-2419,0.00;4,5,-1,5570,4395,0.00;4,6,-1,5570,4395,0.00;4,7,-1,5570,4395,0.00;4,8,-1,5570,4395,0.00;4,9,-1,5570,4395,0.00;4,10,-1,5570,4395,0.00;4,11,-1,5570,4395,0.00;4,12,-1,5570,4395,0.00;4,13,-1,5570,4395,0.00;4,14,-1,5570,4395,0.00;-1,15,-1,913,-3533,0.00;4,16,-1,5570,4395,0.00;4,17,-1,5570,4395,0.00;4,18,-1,5570,4395,0.00;4,19,-1,5570,4395,0.00;4,20,-1,5570,4395,0.00;4,21,-1,5570,4395,0.00;4,22,-1,5570,4395,0.00;4,23,-1,5570,4395,0.00;4,24,-1,5570,4395,0.00;4,25,-1,5570,4395,0.00;4,26,-1,5570,4395,0.00;4,27,-1,5570,4395,0.00;4,28,-1,5570,4395,0.00;4,29,-1,5570,4395,0.00;:117,-1392,7,7.07,A,Dead;:"];
for (var i = 0; i < chucks.length; i++){
splitChucks.push(chucks[i].split(':'))
}
for (var h = 0; h < splitChucks.length; h++) {
alert("This is the unique ID " + splitChucks[h][0]);
alert("This is the teamVal " + splitChucks[h][1]);
}
Hope this helps, this is a much more efficient way to do your task :)
var splitChucks = [];
var chucks = [ "1479661:-1,1,-1,-898,-769,0.00;-1,2,-1,-96,-1402,0.00;-1,3,-1,117,-1397,0.00;-1,4,-1,-4,-2420,0.00;4,5,-1,5570,4395,0.00;4,6,-1,5570,4395,0.00;4,7,-1,5570,4395,0.00;4,8,-1,5570,4395,0.00;4,9,-1,5570,4395,0.00;4,10,-1,5570,4395,0.00;4,11,-1,5570,4395,0.00;4,12,-1,5570,4395,0.00;4,13,-1,5570,4395,0.00;4,14,-1,5570,4395,0.00;-1,15,-1,913,-3533,0.00;4,16,-1,5570,4395,0.00;4,17,-1,5570,4395,0.00;4,18,-1,5570,4395,0.00;4,19,-1,5570,4395,0.00;4,20,-1,5570,4395,0.00;4,21,-1,5570,4395,0.00;4,22,-1,5570,4395,0.00;4,23,-1,5570,4395,0.00;4,24,-1,5570,4395,0.00;4,25,-1,5570,4395,0.00;4,26,-1,5570,4395,0.00;4,27,-1,5570,4395,0.00;4,28,-1,5570,4395,0.00;4,29,-1,5570,4395,0.00;:117,-1397,7,7.00,A,Dead;:", "1479662:-1,1,-1,-898,-769,0.00;-1,2,-1,-96,-1402,0.00;-1,3,-1,117,-1392,0.00;-1,4,-1,-6,-2419,0.00;4,5,-1,5570,4395,0.00;4,6,-1,5570,4395,0.00;4,7,-1,5570,4395,0.00;4,8,-1,5570,4395,0.00;4,9,-1,5570,4395,0.00;4,10,-1,5570,4395,0.00;4,11,-1,5570,4395,0.00;4,12,-1,5570,4395,0.00;4,13,-1,5570,4395,0.00;4,14,-1,5570,4395,0.00;-1,15,-1,913,-3533,0.00;4,16,-1,5570,4395,0.00;4,17,-1,5570,4395,0.00;4,18,-1,5570,4395,0.00;4,19,-1,5570,4395,0.00;4,20,-1,5570,4395,0.00;4,21,-1,5570,4395,0.00;4,22,-1,5570,4395,0.00;4,23,-1,5570,4395,0.00;4,24,-1,5570,4395,0.00;4,25,-1,5570,4395,0.00;4,26,-1,5570,4395,0.00;4,27,-1,5570,4395,0.00;4,28,-1,5570,4395,0.00;4,29,-1,5570,4395,0.00;:117,-1392,7,7.07,A,Dead;:"];
for (var i = 0; i < chucks.length; i++){
splitChucks.push(chucks[i].split(':'))
}
for (var h = 0; h < splitChucks.length; h++) {
alert("This is the unique ID " + splitChucks[h][0]);
alert("This is the teamVal " + splitChucks[h][1]);
}
One of the best purposes of an unique ID is to act as an index. So, instead of iterating over your index array (chunkOne), use ID as an Object key!
// 1479661:-1,1,-1,-898,-769,0.00;-1,2,-1,-96,-1402,0.00;-1,3,-1,117,-1397,0.00;-1,4,-1,-4,-2420,0.00;4,5,-1,5570,4395,0.00;4,6,-1,5570,4395,0.00;4,7,-1,5570,4395,0.00;4,8,-1,5570,4395,0.00;4,9,-1,5570,4395,0.00;4,10,-1,5570,4395,0.00;4,11,-1,5570,4395,0.00;4,12,-1,5570,4395,0.00;4,13,-1,5570,4395,0.00;4,14,-1,5570,4395,0.00;-1,15,-1,913,-3533,0.00;4,16,-1,5570,4395,0.00;4,17,-1,5570,4395,0.00;4,18,-1,5570,4395,0.00;4,19,-1,5570,4395,0.00;4,20,-1,5570,4395,0.00;4,21,-1,5570,4395,0.00;4,22,-1,5570,4395,0.00;4,23,-1,5570,4395,0.00;4,24,-1,5570,4395,0.00;4,25,-1,5570,4395,0.00;4,26,-1,5570,4395,0.00;4,27,-1,5570,4395,0.00;4,28,-1,5570,4395,0.00;4,29,-1,5570,4395,0.00;:117,-1397,7,7.00,A,Dead;:
var data =
{
1479661:
[
-1,1,-1,-898,-769,0.00,-1,2,-1,-96,-1402,0.00,-1,3,-1,117,-1397,0.00,-1,4,-1,-4,-2420,0.00,4,5,-1,5570,4395,0.00,4,6,-1,5570,4395,0.00,4,7,-1,5570,4395,0.00,4,8,-1,5570,4395,0.00,4,9,-1,5570,4395,0.00,4,10,-1,5570,4395,0.00,4,11,-1,5570,4395,0.00,4,12,-1,5570,4395,0.00,4,13,-1,5570,4395,0.00,4,14,-1,5570,4395,0.00,-1,15,-1,913,-3533,0.00,4,16,-1,5570,4395,0.00,4,17,-1,5570,4395,0.00,4,18,-1,5570,4395,0.00,4,19,-1,5570,4395,0.00,4,20,-1,5570,4395,0.00,4,21,-1,5570,4395,0.00,4,22,-1,5570,4395,0.00,4,23,-1,5570,4395,0.00,4,24,-1,5570,4395,0.00,4,25,-1,5570,4395,0.00,4,26,-1,5570,4395,0.00,4,27,-1,5570,4395,0.00,4,28,-1,5570,4395,0.00,4,29,-1,5570,4395,0.00,117,-1397,7,7.00,"A","Dead"
]
// More data...
};
Object.keys(data).forEach(function(key)
{
console.log('This is ID ' + key);
data[key].forEach(function(value,index,array)
{
console.log('Index ' + index + ' of data key ' + key + ':');
console.log(data[key][index]);
});
});
Test this on any modern browser's console or node.js instance to see results.

Working on script in google-apps-script, any suggestions?

Problem: I am creating an array, or multiple arrays, to write values, and continue doing so until a certain value is drawn. The long view for this code is to, using these values to match one letter to another. (i.e. The Bombe used in WWII.) Except this will be completely digital. The Bombe was a decrypter that find that one letter is able to get mapped to another. (Enigma example will be posted in comments.) I am trying to decrpyt any message using this.
Understanding: I don't remember a lot of code especially since I have never used google-apps-script before. I no basic ideas, but some of the syntax's are different I am getting lost. (i.e.: instead of System.out.print(); it would be Logger.log(data);. That's really all I have gotten from it so far. I have some code worked out which can be found here.
Background: This is quite a lot of text to read I understand, but hear me out before you just flag me and move on. The hyperlink posted in the above comment under the words "Enigma example" shows the mapping that I am trying to do in reverse. I however need to create loops and variables that I do not remember how to create. I have information on the Enigma and Bombe: Enigma & Bombe info. I have done some searches on Google and the like, however nothing that I understand or benefit my end goal. All I have gotten is another link, which I will post in the comments, that shows me a basic loop as they put it.
What I need help with: I am asking for help in the following: Looping, variables and arrays. Suggestions will be the most valuable to me, because I am here to learn, not get my stuff done done by asking.
Ideas: Some ideas I have are, Garbage collectors, multi-dimensional array and/or just a sequence of possibilities. (See the "Enigma & Bombe info" link above.
For easy Copy/Pasting:
function bombeCode1() {
var fastRotor = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var mediumRotor = fastRotor;
var slowRotor = fastRotor;
var rows = 26;
var columns = 26;
for (var i=0; i < rows ; i++) {
Logger.log('Outer Loop: value of i : ' + i);
// Logger.log("Partition for Outer Loop");
// Logger.log(" ");
var fastRotorValue = fastRotor[i];
for (var j=0; j < columns ; j++) {
Logger.log('-Inner Loop value of j : ' +j);
//var fastRotorValue = fastRotor[i];
var medRotorValue = mediumRotor[j];
// Logger.log("---- " + fastRotorValue + " " + medRotorValue);
for (var k=0; k < 26 ; k++) {
// Logger.log('---- XXXX Third Loop value of k : ' + k);
//var fastRotorValue = fastRotor[i];
//var medRotorValue = mediumRotor[j];
var slowRotorValue = slowRotor[k];
Logger.log("---- XXXX " + fastRotorValue + " " + medRotorValue + " " + slowRotorValue);
}; //var objectNumberValuePair = {"0":"A", "1":"B", "2":"C","3":"D","4":"E","5":"F","6":"G","7":"H","8":"I",
// "9":"J","10":"K","11":"L","12":"M","13":"N","14":"O","15":"P","16":"Q","17":"R",
// "18":"S","19":"T","20":"U","21":"V","22":"W","23":"X","24":"Y","25":"Z"}
// Logger.log(slowRotorValue = objectNumberValuePair);
// Logger.log(medRoterValue = objectNumberValuePair);
// Logger.log(fastRoterValue = objectNumberValuePair);
}
}
}
Here is the code I modified a little bit, just to show the Loop values in the Logger print out.
function bombeCode1() {
var fastRotor = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var mediumRotor = fastRotor;
var slowRotor = fastRotor;
var rows = 3;
var columns = 6;
for (var i=0; i < rows ; i++) {
Logger.log('Outer Loop: value of i : ' + i);
Logger.log("Partition for Outer Loop");
Logger.log(" ");
for (var j=0; j < columns ; j++) {
Logger.log('----Inner Loop value of j : ' + j);
var fastRoterValue = fastRotor[i];
var medRoterValue = mediumRotor[j];
Logger.log("---- " + fastRoterValue + " " + medRoterValue);
for (var k=0; k < 6 ; k++) {
Logger.log('---- XXXX Third Loop value of k : ' + k);
var fastRoterValue = fastRotor[i];
var medRoterValue = mediumRotor[j];
var slowRotorValue = slowRotor[k];
Logger.log("---- XXXX " + fastRoterValue + " " + medRoterValue + " " + slowRotorValue);
};
}
}
}
Run it and see what you think. I'm sure it's not what you need, but got to start somewhere.

How to get length string json in js or jQuery

i have this code,
buildSelect: function (data) {
var response = $.parseJSON(data);
alert(response.length);
var s = "<select>";
if (response && response.length) {
for (var i = 0, l = response.length; i < l; i++) {
var ri = response[i];
s += '<option value="' + ri.CUSTOMS_ID + '">'
+ ri.CUSTOMS_NAME + '</option>';
}
}
return s + "</select>";
}
},
i want check response is n't null or empty and get length i write this code response.length
but return undifine
and data return
{"rows":[{"id":1,"cell":["1","بندرامام خميني","IMAM KHOMEINI PORT","True",null]},{"id":2,"cell":["2","آبادان","ABADAN","True",null]},{"id":3,"cell":["3","خرمشهر","KHORRAMSHAHR","True",null]},{"id":4,"cell":["4","بندرعباس","BANDAR ABBAS","True",null]},{"id":5,"cell":["5","بوشهر","BUSHEHR","True",null]},{"id":6,"cell":["6","تهران","TEHRAN","True",null]},{"id":7,"cell":["7","شيراز","SHIRAZ","True",null]},{"id":8,"cell":["8","دبي","DUBAI","True",null]}],"Page":0,"Total":0,"Records":0}
i want if Rows isn't empty all child add to DropDownlist
plese help me, thanks
The issue is that response doesn't have a length property. However, response.rows, as an Array, does:
var response = $.parseJSON(data);
alert(response.rows.length);
You could then save a reference to response.rows and use that going forward:
var rows = response.rows;
alert(rows.length);
var s = "<select>";
if (rows && rows.length) {
for (var i = 0, l = rows.length; i < l; i++) {
var ri = rows[i];
s += '<option value="' + ri.id + '">' + ri.cell[1] + '</option>';
}
}
return s + "</select>";
$.parseJSON(data) returns JavaScript object and not a string. You cannot use length on an object. According to documentation $.parseJSON will return null if you pass in nothing, an empty string, null, or undefined.
UPD:
In your particular case it is enough to check that response is not null (no need to check the length). If data is not a valid JSON then $.parseJSON(data) will through an exception. You may want to catch it as well.
Once you've parsed the JSON string, in this case, you will get an Object in you var response. JavaScript objects do not have a length property. If you just want to check for a null or empty value then do one or more of the following.
var data = "";//in case of null data
if(!data){
//do something
}
//or
if(data === ''){
//do something
}
Now, if you want to check whether your rows are empty,
var data = {
rows:{}
};//assuming an empty rows object
if($.isEmptyObject(data.rows)){
//do something
}
Since object does not contain length property/method and there is no sense for length of object.you can assign methods and properties to each object, pre-written or self-defined.
In your case try to search for object data/properties,like
for(keys in response){
check some properties related on keys
}

Categories