How to add array items in javascript? - javascript

In a wordpress plugin, there is a field box called 'data' where I can add code for it to pull, below in the code where it says 'data =' that is me referencing the box. In the box:
What I put in the field box entitled 'data':
{
contacts: [
{ name: "Name 1", email: "email1#test.com" },
{ name: "Name 2", email: "email2#test.com" }
]
};
This is what I put in the global field box, for it to apply to everything.
function (jQueryPopoverObj, mapObject, mapsvgInstance) {
// "this" = clicked mapObject
if(this.mapsvg_type == "region"){
return '<b>'+this.id+'</b>' +
this.data.contacts.map(function(contact) {
return contact.name + '<br>' +
'' + contact.email + ''
}).join('<br>');
} else if (this.mapsvg_type == "marker"){
return 'Marker - <b>'+this.id+'</b>, contact: '+this.data.email;
}
}
I want to also add { seat: "County Seat"} to the data portion and add it in the function.
I tried adding a line in the contacts, and then adding + '<br>' + contact.seat, after return contact.name, with no luck. Basically when it does the popover (which it pulls from global function for the template and the information from the data field box), I want it to have the CountySeat under the County Name (e.g. the County Seat for Harris County is Houston, so it would have Houston under Harris County).
Example of Lubbock County without the City name under it

var data = {
contacts: [
{ name: "Name 1", email: "email1#test.com" },
{ name: "Name 2", email: "email2#test.com" }
]
}
To add a new property seat you can simply do this-
data["seat"] = "County Seat"
or
data.seat = "County Seat"
JSFiddle

It looks like you want to set the seat assignment on the contact? You'd have to get the contact from the array, looping through each one and figuring out the one you want to use, then do contact.seat = "XYZ", which will add a seat property to the contact object. You can then use contact.seat in the string output but you have to null check it because it may be null. To help with that, I'd recommend defaulting it to an empty string like:
data = {
contacts: [
{ name: "Name 1", email: "email1#test.com", seat: "" },
{ name: "Name 2", email: "email2#test.com", seat: "" }
]
}
And then change it when it is assigned.

Related

Typeahead + Bloodhound - Have to enter additional character to see data source change

I have to code to get source from different endpoints for typeahead based on number of characters entered in input field. However the suggestions from new source are displayed only after entering extra character. Suggestions that should show after input length is 3 are showing up on entering 4 chraracters
I have created sample of problem in jsfiddle
http://jsfiddle.net/yj7hdzka/
In the sample new suggestion from new data source with title "some title here3" should show as soon as I entered 3 characters but doesnt show until 4 characters are entered in input field.
Here is html and javascript
<input type="text" id="search-input">
<button id="switch">Switch Data Source</button>
<span id="sourceSelected"></span>
var data1 = [{
label: "some title here1",
desc: "some option here1",
category: [{
name: "category 1"
}, {
name: "categoy 2"
}]
}, {
label: "some title here2",
desc: "some option here2",
category: [{
name: "category 1"
}, {
name: "categoy 2"
}]
}];
var data2 = [{
label: "some title here3",
desc: "some option here3",
category: [{
name: "category 1"
}, {
name: "categoy 2"
}]
}, {
label: "some title here4",
desc: "some option here4",
category: [{
name: "category 1"
}, {
name: "categoy 2"
}]
}];
var titles = new Bloodhound({
datumTokenizer: function (data) {
return Bloodhound.tokenizers.whitespace(data.label);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: data1
});
titles.initialize();
$('#search-input').typeahead({
highlight: true
}, {
name: 'titles',
displayKey: 'label',
source: titles.ttAdapter()
});
var sourceSelected = $('#sourceSelected');
var toggle = false;
$('#search-input').keyup(function(){
if($('#search-input').val().length > 2){
titles.local = data2;
sourceSelected.text('Data Source 2');
} else {
titles.local = data1;
sourceSelected.text('Data Source 1');
}
titles.initialize(true);
});
sourceSelected.text('Data Source 1');
I faced two different problems while trying to find a solution:
the latest typeahead version seems to be less stable than the previous version 0.10.2 (and the Original twitter project is considered dead, some community forks exist and are maintained).
a bound data source does not react to updates properly.
What I changed:
Switched to the 0.10.2 typeahead bundle.
manually added Bloodhound search result.
Updated code:
var filter = function(suggestions) {
return $.grep(suggestions, function(suggestion) {
return -1;
});
}
var titles = new Bloodhound({
name: 'titles',
datumTokenizer: function(data) {
return Bloodhound.tokenizers.whitespace(data.label);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: data1
});
titles.initialize();
$('#search-input').typeahead({
highlight: true
}, {
name: 'titles',
displayKey: 'label',
source: function(query, callbackFunc) {
titles.clear();
if ($('#search-input').val().length > 2) {
titles.local = data2;
sourceSelected.text('Data Source 2');
} else {
titles.local = data1;
sourceSelected.text('Data Source 1');
}
titles.initialize(true);
titles.get(query, function(suggestions) {
callbackFunc(filter(suggestions));
});
}
});
Part of my answer has been taken from this SO answer and to be honest, I don't exactly know how the get() method of the typeahead plugin was implemented and why it requires a callback function as seen in my solution.
Here's a working jsfiddle, I hope that's what you were looking for.

Angularjs splice array of objects inside of an object always removes last object

I have an object which contains an array of objects called "blocks":
$scope.microsite = {
images: [
{url: "https://unsplash.it/800/400/?image=20"},
{url: "https://unsplash.it/800/400/?image=15"},
{url: "https://unsplash.it/800/400/?image=52"}
],
blocks: []
};
When I add stuff to this array, it behaves perfectly normally:
$scope.addElement = function(a){
if(a=='heroslider'){
var data = {
slides: [
{
id:0,
image:0,
title: "Title",
desc: "Description",
},
{
id:1,
image:1,
title: "Title",
desc: "Description",
},
{
id:2,
image:2,
title: "Title",
desc: "Description",
}
]
};
} else if(a=='threecol'){
var data = {
columns: [
{
title: "Column one",
text: "This is a column for features",
},
{
title: "Column two",
text: "This is a column for features",
}
]
};
}
var element = {
template: a,
data: data
};
$scope.microsite.blocks.push(element);
}
However when I try to remove an object from the array by calling this function on ng-click and passing in the object from an ng-repeat...
$scope.removeElement = function(element){
var x = $scope.microsite.blocks.indexOf(element);
console.log($scope.microsite.blocks[x]);
console.log(x);
$scope.microsite.blocks.splice(x, 1);
}
I am able to get both the correct object and the correct index in my console, but when it goes to splice the array, the last object is always being deleted which is very strange as this should only be happening when the index I'm trying to delete doesn't exist (and therefore would equal -1)
Any ideas why this could be happening?
EDIT: I have also tried using ng-click="microsite.blocks.splice($index, 1)" directly in the element, as well as passing the $index into the function instead of the element. In all cases, the correct index is found, but the result is still the same, only the last entry is ever deleted.
Turns out this was an error with "track by $index" in Angular. After removing "track by $index" from my ng-repeat, splice() functioned normally.

Elastic-search: How can i map json data having dynamic number of fields

I'm working on a application for that i need to map json data for storing in Elasticsearch. The number of fields in json data is dynamic.then how can i do mapping for this scenario.
mapping Snippet
var fs = uploadedFiles[0].fd;
var xlsxRows = require('xlsx-rows');
var rows = xlsxRows(fs);
console.log(rows);
client.indices.putMapping({
"index": "testindex",
"type": "testtype",
"body": {
"testtype": {
"properties": {
"Field 1": {
"type": "string"
},
"Field 3": {
"type": "string"
},
"Field 2":{
"type":"string"
} .....
//Don't know how many fields are in json object.
}
}
}
}, function (err, response) {
if(err){
console.log("error");
}
console.log("REAPONCE")
console.log(response);
});
This is my sample json data
//result of rows
[
{ Name: 'paranthn', Age: '43', Address: 'trichy' },
{ Name: 'Arthick', Age: '23', Address: 'trichy' },
{ Name: 'vel', Age: '24', Address: 'trichy' } //property fields
]
NOTE: The number of property fields are dynamic.
ES will always make its best efforts to infer the correct type for the fields in your documents that have no mapping defined and set sensible defaults.
A mapping is only necessary if you need to apply some special treatment to certain fields other than the set defaults, like specifying an indexing analyzer, a search analyzer, whether string fields need to be analyzed or not, specifying sub-fields with a different analyzer, etc.
If you don't need any of this, then you can let ES infer the mapping of your documents.

Search by name and family but display account number in jquery autocomplete

I'm working on a piece of code which has used jquery ui autocomplete component in order filter searched items. I have to configure it in order to be available to search based on multi ple factors, here is my sample search array:
var availableTags = [{
name: "Smith",
family: "Johnson",
account_number: "10032",
nick_name: "Friend account",
}, {
name: "Susan",
family: "Rice",
account_number: "343243",
nick_name: "Mom Account",
}, {
name: "Joe",
family: "Austin",
account_number: "3434",
nick_name: "Partner Account",
}, {
}];
the auto complete should display name, family, account number and nick_name when displaying the suggestion box. but when each item is selected only the account_number must be inserted into the text box. user must also be able to search through name, family, account number and nick name all of them. How can i achieve this target?
You need to:
Revise the data array to contain the value parameter (this allows autocomplete to fill the input upon focus/select)
Write a custom source function that filters the data based on what user has typed
Write a custom _renderItem function that displays the data formatted to your liking
So you have:
var userData = [{
name: "Smith",
family: "Johnson",
value: "10032",
nick_name: "Friend account"
}, {
name: "Susan",
family: "Rice",
value: "343243",
nick_name: "Mom Account"
}, {
name: "Joe",
family: "Austin",
value: "3434",
nick_name: "Partner Account"
}];
$("#autocomplete").autocomplete({
source: function (request, response) {
var search = $.trim(request.term.toLowerCase());
var array = $.grep(userData, function (val) {
return
val.name.toLowerCase().indexOf(search) >= 0 ||
val.family.toLowerCase().indexOf(search) >= 0 ||
val.value.toLowerCase().indexOf(search) >= 0 ||
val.nick_name.toLowerCase().indexOf(search) >= 0;
});
response(array);
}
})
.data("ui-autocomplete")._renderItem = function (ul, item) {
var $a = $("<a></a>").text(item.name + " " + item.family);
$("<br />").appendTo($a);
$("<small></small>").text(item.nick_name).appendTo($a);
$("<br />").appendTo($a);
$("<small></small>").text(item.value).appendTo($a);
return $("<li></li>").append($a).appendTo(ul);
};
Demo here

Create Dynamic Menu based on the ID of right clicked DOM element

I want to Create Dynamic Menu based on the ID of right clicked DOM element. so that I can show the Menu for particular user eg: "Label For 23"
I am using the Context Menu something like this,
$.contextMenu({
selector: 'tr',
callback: function (key, options) {
var m = "clicked: " + key;
var temp = $(this);
if (key == "Rebate") DoInvoice();
},
items: {
"Credit Note": { name: "Credit Note " },
"Full Refund": { name: "Full Refund " },
"Partial Refund": { name: "Partial Refund " },
"Rebate": { name: "Rebate " }
}
});
Currently I am getting the Context Menu on right click as shown in the Image below,
But I want to show that in Format like
"Credit Note For 130",
"Full Refund For 130",
"Partial Refund For 130",
"Rebate For 130"
Please help me on this ASAP.
Try this:-
var userid;
// Get the ID, when rightclick event is fired & set the ID to above variable.
items: {
"Credit Note For"+ userid : { name: "Credit Note " },
"Full Refund For"+ userid : { name: "Full Refund " },
"Partial Refund For"+ userid : { name: "Partial Refund " },
"Rebate For"+ userid : { name: "Rebate " }
}

Categories