Bootstrap selectpicker val won't accept an object just string - javascript

I want to understand one behavior from selectpicker. I'm trying load this this element with one attribute from my session:
Template.checkNotification.onRendered(function () {
var currentNotification = Session.get("currentNotification");
this.$('#symptoms1').selectpicker({
multipleSeparator: ' ',
});
this.$('#symptoms2').selectpicker({
multipleSeparator: ' ',
});
var symptoms = [];
for (var symptom of currentNotification.symptom.symptoms) {
symptoms.push('"' + symptom.name + ';;' + symptom.value + '"');
}
var symptomsSelected = symptoms.join(", ");
var test1 = ['Dor de Cabeça;;dor-de-cabeca','Náusea;;nausea'];
var test2 = "["+symptomsSelected+"]";
this.$('#symptoms1').selectpicker('val', test1);
this.$('#symptoms2').selectpicker('val', test2);
});
When I execute this code, only the element #symptom1 works and loads the proper options into the selectpicker.
How can I build an array of option to provide to selectpicker?

If you want to pass the symptoms to the selectpicker, you need to provide it as a native array. This code builds the array the original way and the new way (suitable for assigning to the val):
var currentNotification = {
symptom: {
symptoms: [
{ name: "symptom1", value: "value1" },
{ name: "symptom2", value: "value2" },
{ name: "symptom3", value: "value3" },
{ name: "symptom4", value: "value4" },
{ name: "symptom5", value: "value5" }
]
}
};
var symptoms = [];
for (var symptom of currentNotification.symptom.symptoms) {
symptoms.push('"' + symptom.name + ';;' + symptom.value + '"');
}
var symptomsSelected = symptoms.join(", ");
var test1 = "["+symptomsSelected+"]";
var test2 = $.map(currentNotification.symptom.symptoms, function(symptom) {
return symptom.name + ';;' + symptom.value;
});
console.log("test1: ", typeof test1, " value: ", test1);
console.log("test2: ", typeof test2, " value: ", test2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
How does this work? The jQuery $.map function will process each of the symptoms from the currentNotification.symptom.symptoms array, and format them individually for use with selectpicker. Each element is formatted, but the array is left as a native Javascript array, with each element corresponding to the original currentNotification.symptom.symptoms array.
Compare the results of test1 and test2 to see the difference:
test1: string value: ["symptom1;;value1", "symptom2;;value2", "symptom3;;value3", "symptom4;;value4", "symptom5;;value5"]
test2: object value: [
"symptom1;;value1",
"symptom2;;value2",
"symptom3;;value3",
"symptom4;;value4",
"symptom5;;value5"
]
Note that in this example code, test1 is a string, which is formatted like an array. This resembles a JSON array value, not a native Javascript array value. test2 is a Javascript array suitable for use with selectpicker.
Using the $.map solution will solve your current problem and produce a proper Javascript array. Now, you can use this to set the val of the selectpicker:
this.$('#symptoms2').selectpicker('val', test2);

plunker: http://plnkr.co/edit/sjwK1e?p=preview
$scope.symptomsSelected="["+'"\My selected item is string\"'+"]"
$scope.test2 =angular.fromJson($scope.symptomsSelected);
$scope.test2=$scope.test2[0];
{{test2}}
<br>
{{symptomsSelected}}

Related

Create One string from elements in an Array of Objects

I am trying to create ONE string from an array of objects family and have them separated by commas except for the last element Mary
const family = [
{Person: {
name: John
}}, {Person: {
name: Mike
}}, {Person: {
name: Link
}}
, {Person: {
name: Mary
}}];
I want the string to be like this
"John, Mike, Link or Mary"
I tried using family.toString() but that gives me "John, Mike, Link, Mary" and doesn't allow me to replace "," with an "OR"
Use pop() to get (and remove) the last name. Then use join() to add the rest.
Thx to #charlietfl for suggesting a check on the number of names to prevent something like: and John.
const family = [
{ Person: { name: "John" } },
{ Person: { name: "Mike" } },
{ Person: { name: "Link" } },
{ Person: { name: "Mary" } }
];
// Get all the names
const names = family.map((x) => x.Person.name);
// Get result based on number of names
let result = '';
if (names.length === 1) {
// Just show the single name
result = names[0];
} else {
// Get last name
const lastName = names.pop();
// Create result
result = names.join(', ') + ' and ' + lastName;
}
// Show output
console.log(result);
I don't think there's a super-elogant option. Best bet is something like:
function joinWord(arr, sep, finalsep) {
return arr.slice(0,-1).join(sep) + finalsep + arr[arr.length-1];
}
and then
joinWord(family.map(x=>x.person.name), ', ', ' or ');
You could make the invocation a little nicer at the cost of performance and modularity with:
Array.prototype.joinWord = function joinWord(sep, finalsep) {
return this.slice(0,-1).join(sep) + finalsep + this[this.length-1];
}
family.map(x=>x.person.name).joinWord(', ', ' or ')
But this is only a good idea if this is going to come up a lot within your program and your program is never going to be a part of something bigger. It effects every array.
How about
let sp = ' or ';
family.map(x => x.Person.name)
.reduceRight(
(x,y) => {
const r = sp + y + x;
sp = ', ';
return r;
}, '')
.replace(', ', '');
Hope, this question was for the school homework :)

Iterating over a json array whose key value is dynamic

I have a json structure as:
{
"TestCaseList": [
{
"TC_1": {
"name":"verifyloginpagedetails",
"value":"2"
},
"TC_2": {
"name":"verify registration page details",
"value":"3"
}
}
],
"Summary": {
"v":[
{
"name":"over the ear headphones - white/purple",
"value":1
}
]
}
}
How to extract the values name, value of TC_1 , TC_2 where TC_1 is dynamic i.e. key of TestCaseList?
You can use the Object.keys method to get an array of the keys of an object.
With a single object in the array at "TestCaseList" in your JSON object, this will work:
// jsonObj is your JSON
testCaseKeys = Object.keys(jsonObj.TestCaseList[0]);
If, however, the array at "TestCaseList" contains more than one one element, you can use this to get each set of keys in an individual array:
testCaseKeySets = jsonObj.TestCaseList.map(obj => Object.keys(obj));
I'm sure a more elegant solution exists, but this will do the trick.
var myObj = {
"TestCaseList":
[{
"TC_1":
{"name":"verifyloginpagedetails",
"value":"2"},
"TC_2":
{"name":"verify registration page details",
"value":"3"}
}],
"Summary":{
"v":[{"name":"over the ear headphones - white/purple","value":1}]
}
}
let testCaseListKeys = Object.keys(myObj.TestCaseList[0]);
for(i=0; i < testCaseListKeys.length; i++){
let tclKey = testCaseListKeys[i];
console.log(tclKey + "\'s name = " + myObj.TestCaseList[0][tclKey].name);
console.log(tclKey + "\'s value = " + myObj.TestCaseList[0][tclKey].value);
}
The console.logs are your output. The important values there are the myObj.TestCaseList[0][tclKey].name and the myObj.TestCaseList[0][tclKey].value
** UPDATE **
After answering the question Ananya asked how to do this same thing if the object had a different structure.
Updated Object:
var myObj2 = {
"TestCaseList":
[{
"TC_1":{
"name":"verifyloginpagedetails",
"value":"2"}
},
{
"TC_2":{
"name":"verify registration page details",
"value":"3" }
}],
"Summary":
{
"v":[ {"name":"over the ear headphones - white/purple","value":1} ]
}
}
Updated JavaScript:
for(x=0;x<myObj2.TestCaseList.length;x++) {
let testCaseListKeys = Object.keys(myObj2.TestCaseList[x]);
for(i=0; i < testCaseListKeys.length; i++){
let tclKey = testCaseListKeys[i];
//console.log(tclKey);
console.log(tclKey + "\'s name = " + myObj2.TestCaseList[x][tclKey].name);
console.log(tclKey + "\'s value = " + myObj2.TestCaseList[x][tclKey].value);
}
}

Get values from nested array that are dynamically generated

I am working on a chrome plugin that fetches data. But now i have been running into a problem, I have been asked to put together a nested array with all the data I have retrieved but I have no clue on how to pull this off.
What i want to create:
var messagedata [{
time: messageTime,
Date: messageDate,
Text: messageText
{
time: messageTime,
Date: messageDate,
Text: messageText
}
}];
Note that I know how to create the above when I have the variables. That is not the problem. But in this case i do not know how to declare the variables for each message from the array that is generated.
What i need is a nested array for each message that is in the HTML. So the above example displays 2 arrays but it could be 54 for example.
Code i use to generate normal array:
adiv.innerHTML = cleanupDocString;
trs = adiv.querySelectorAll('tr[bgcolor="#FFFFFF"]');
trs.forEach(function(tr) {
var d = [];
tr.querySelectorAll("td")
.forEach(function(td) {
var img = td.querySelector("img"),
src = img && img.attributes.getNamedItem("src").value;
d.push(src || td.textContent);
});
msgs.push(d);
});
The code above puts this out in console (this example has 2 messages inside it, there are also arrays with 54 messages):
0:Array(6)
0:"2017-08-31T00:00:00"
1:"13:22"
2:"MessageType"
3:”ClientName"
4:"Subject "
5:"messageText"
length:6
proto:Array(0)
1:Array(6)
0:"2017-08-31T00:00:00"
1:"13:21"
2:" MessageType "
3: "ClientName"
4:" Subject "
5:" messageText "
lenth:6
proto:Array(0)
To make the question easier:
I need to know how i can put the data into a variable that i fetch from the array above. I just don't know how to do it so its dynamic.
What i tried:
var messageDate = msgs[0][0];
var messageTime = msgs[0][1];
var messageType = msgs[0][2];
var messageClient = msgs[0][3];
var messageSubject = msgs[0][4];
var messageText = msgs[0][5];
The above code works but only fetches the first message. I need all the messages that are on the page that is provided. I tried using a ID in the first [] but that also didn't give me the desired result.
Thanks for your help and patience in advance.
Output and code has been slightly edited so it hides personal information
i am assuming msgs is arrray of arrays and the order of properties is guaranteed
var mappedArray = msgs.map((msg)=> {
return {
messageDate : msg[0];
messageTime : msg[1];
messageType : msg[2];
messageClient : msg[3];
messageSubject : msg[4];
messageText :msg[5];
}
})
Edit1
you can use arrayconcat
var mergedArray = mappedArray.concat(otherArray);
To transform the multidimensional array to an array of objects with the help of Array.prototype.map and a simple helper dictionary which defines the index => property mapping.
var messages = [
[
"2017-08-31T00:00:00",
"13:22",
"MessageType",
"ClientName",
"Subject",
"messageText",
"unwanted value"
],
[
"2017-08-31T00:00:00",
"13:22",
"MessageType",
"ClientName",
"Subject",
"messageText",
"unwanted value"
],
[
"2017-08-31T00:00:00",
"13:22",
"MessageType",
"ClientName",
"Subject",
"messageText",
"unwanted value"
]
];
var mappingDef = {
0: 'messageDate',
1: 'messageTime',
2: 'messageType',
3: 'messageClient',
4: 'messageSubject',
5: 'messageText'
};
function transformMessages(messages, mappingDef) {
return messages.map(function(message) {
var obj = {};
for(var index in mappingDef) {
if(mappingDef.hasOwnProperty(index)) {
obj[mappingDef[index]] = message[index];
}
}
return obj;
});
}
console.log(transformMessages(messages, mappingDef));

Dynamically add link with String parameter

I have a REST backend link mywebsite/guests, which returns list of guests. In the front end, I want to display the guests as links. Here's the code
for(guest of guests) {
$('#guest_list').append('<a onclick="showGuest(' + guest.id + ')">' + guest.name + '</a><br>')
}
function showGuest(id) {
console.log(id)
...
}
I should mention that guest.id is a string.
The console always print undefined. My question, how can I add these links with String parameters?
for(guest of guests) {
$('#guest_list').append('<a onclick="showGuest(this)" data-id='+guest.id+'>' + guest.name + '</a><br>')
}
function showGuest(this) {
console.log($(this).data('id'))
}
The main issue is that you are trying to access the property of dynamically bound DOM elements in your showGuest(id) function. You should use the onClick function in the following way-
var guests = [{"id":1, "name":"John Doe"},
{"id":2, "name":"David Jones"}];
for(guest of guests) {
$('#guest_list').append('<a class="guest" data-id="'+guest.id+'">' + guest.name + '</a><br>');
}
$('#guest_list').on('click', 'a.guest', function() {
var id = $(this).attr('data-id');
$('.message').text('').append("Clicked guest with ID: "+id);
});
Working JSFiddle here - https://jsfiddle.net/2dkpsve8/
Hope this helps!
The way to approach this problem depends on the format and content of the guests variable. If you started with this object:
var guests = {
'123': {id: 123, name: 'joe'},
'234': {id: 234, name: 'jane'}
};
Then key would be "123" and "234" in the following loop, and the object values would be guests[key]:
for(var key in guests) {
$('#guest_list').append('<a onclick="showGuest(' + guests[key].id + ')">' + guests[key].name + '</a><br>')
}
function showGuest(id) {
console.log(id)
...
}
But if you're already using jQuery, take a look at jQuery.each for another looping option.
On the other hand, if guests is an array, as in:
var guests = [
{id:"123", name:"joe"},
{id:"234", name:"jane"}
];
then you will just want to use something like:
for(var i=0; i < guests.length; i++) {
// id is guests[i].id
// name is guests[i].name
}
Amazingly,
$('#guest_list').append('<a onclick="showGuest(' + "guest.id" + ')">' + guest.name + '</a><br>')
works fine! I don't know way. "guest.id" is replaced by the actual id of guest.

Loop Through Multivalue Array

First of all sorry if I have the terminology wrong, if so could you please correct me?
I am trying to loop through the following javascript array.
var pieData2 = [
{
label: 'wow',
value: 30,
color:"#F38630"
},
{
label: 'wow2',
value : 10,
color : "#E0E4CC"
},
{
label: 'wow3',
value : 100,
color : "#69D2E7"
}
];
I am trying to write the label and color into separate divs. I have tried the following concept, but have got no where.
$.each( pieData2[0], function( key, value ) {
alert( key + ": " + value );
});
The jQuery.each() function is designed to iterate over a collection, such as the elements in an array or over the properties of an object. In your case, it's iterating over an array of objects. In your code, pieData2 is your array, so you want to pass that as the first argument to $.each(). The second argument is a function that will handle each iteration, and has two parameters: index and value (though you can name them whatever you wish).
$.each(pieData2, function(index, value) {
// index will be 0, 1, 2
// value will be equivalent to pieData2[0], pieData2[1], pieData2[2]
console.log(value.label); // outputs wow, wow2, wow3
});
As has been used in another answer, you can also use the this keyword to refer to the element being looked at for that iteration, so this and value in the above code are the same.
http://jsfiddle.net/X5r8r/1119/
var pieData2 = [
{
label: 'wow',
value: 30,
color:"#F38630"
},
{
label: 'wow2',
value : 10,
color : "#E0E4CC"
},
{
label: 'wow3',
value : 100,
color : "#69D2E7"
}
];
$.each( pieData2, function( key, value ) {
alert( key + ": " + value['label'] +" value: " + value['value']);
});
each is fine, but you need to loop over pieData2 not over the first element of pieData2...
$.each( pieData2, function() {
alert( this.label + ": " + this.value );
});
http://jsfiddle.net/3anAJ/
Try this
$.each( pieData2, function(index) {
alert("label = " +pieData2[index].label+ " color = " +pieData2[index].color);
});
You do not need jQuery for this. In cases where jQuery really isn't needed, I don't really suggest it. At that point it's just kind of pointless. Use regular JS where possible, use jQuery where needed.
for (var i = 0; i < pieData2.length; i++) {
alert(pieData2[i].label + ' : ' + pieData2[i].value);
}
If you really want to use jQuery, since $.each can iterate over arrays AND objects, you can just use it to iterate over the array and alert each.
This will iterate over each object in the array and alert each key, value pair...
$.each(pieData2, function (key, obj) {
alert(obj.label + ' : ' + obj.value);
});
If you need to iterate over the array and over each object (if you do not know the length), then you can do:
for (var i = 0; i < pieData2.length; i++) {
for (var prop in pieData2[i]) {
if (pieData2[i].hasOwnProperty(prop)) {
alert(prop + ' : ' + pieData2[i][prop]);
}
}
}
or
$.each(pieData2, function(obj) {
$.each(pieData2[obj], function(key, value) {
alert(key + ' : ' + value);
});
});

Categories