Searching in angular.js using id - javascript

I have two json:
all_users
"all_users":
{
"4":{
"user_id":4,
"user_name":"Miranda"
},
"7":{
"user_id":7,
"user_name":"seconduser"
}
And tickets
"tickets":
[{
"ticket_id" : 12,
"created_by" : 7,
"assigned_to": 6
}]
Now, from the json tickets, I need to search who created a ticket, i.e created_by. But, since this is id, I am not able to search it directly using name.
After doing my bit of research, I implemented this:
<input id="created-by-input" type="text" ng-model="search.created_by" placeholder="Created by" typeahead="user.user_id as user.user_name for user in transformationFunction(all_users, $viewValue) | filter:{user_name:$viewValue}" class="form-control">
And the scope:
$scope.transformationFunction = function(object) {
var newArray = [];
for(var key in object) {
newArray.push({user_id: key, user_name: object[key].user_name});
}
return newArray;
console.log(newArray)
};
However, when I am searching, I get all the relevant users when I start typing. Also, when I click on them, the search filter works and shows me the result. But, when I click on the users in the dropdown while searching, the text field shows me the ID and not the user name.
For example: I start typing Mira, the dropdown shows Miranda, when I click on it, the text field shows me 4.
What am I missing out in here??

If you would store your users as an array
e.g.
$scope.users = [{
id: 1,
name: "Fancyname"
},
{
id: 2,
name: "Fancyname2"
}]
You could use the .map function like this:
var index = $scope.users.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor);
var user= $scope.users[index];

Related

Change data before it is displayed, on click of dropdownlist in kendo grid

Is there a way to change the data before it is displayed in a dropdown AS you click to edit the field?
Using a simpler solution and trying to use dataBinding, which is supposed to fire before the data is bound (and available on dropDownList as well), it doesn't appear to be able to change the data before the data runs. Or at least doesn't update it.
The deep dive into the problem is that I want to run a for loop around the array of data, and perform some operations on it, based on the rest of the data in the row.
The simpler idea, is that I want to edit the data before it is displayed, on click of the kendo grid.
https://dojo.telerik.com/UROwaWoN
var mydata = [
{ name: "Jane Doe", age: 30 },
{ name: "John Doe", age: 33 }];
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" }
],
dataSource: mydata,
dataBinding: function(e) {
mydata.push({ name: "Kane Madison", age: 24 });
console.log("dataBinding");
}
});
The answer was that I have to set the datasource again. I did this by setting the datasource within the "edit" function on the options (before the dropdownlist select event). It looks like this:
edit: function(event) {
// .....
if (selectedFieldName == "thefieldIwant") {
let newDataSource = remapDataBased
let dropdownList = ..... (get dropdownlist from Kendogrid)
dropdownList.setDataSource(newDataSource);
}
}
I think it's possible there are other solutions to this, but this has been up a few days and nobody has found them yet.

Load nested JSON array into select in Vue using computed properties

Originally in my Vue component I had a series of nested if statements that would go through the JSON data to determine whether a text input should be displayed or a select based on a has_selectable_value option being true (select display) or false (text input display), and if it was a select then loop through the data and output associated options.
I have been able to change that to a computed statement which almost does everything I need it to do apart from one little thing which is to display the select options.
Here is the relevant part of the Vue Code:
<template v-else-if="searchtype == 9">
<select v-for="service in selectableServices" class="form-control" v-model="searchvalue" required>
<option value="">Select A Location</option>
<option v-for="sl in selectableLocations" :value="sl.location_id">{{sl.name}}</option>
</select>
<input v-for="service in nonSelectableServices" class="form-control" v-model="searchvalue" placeholder="Enter Search Value" required>
</template>
The current computed functions:
services: function () {
var ret = []
this.countries.forEach(function(country) {
country.states.forEach(function(state) {
state.services.forEach(function(service) {
ret.push(service)
});
});
});
return ret;
},
selectableServices: function () {
return this.services.filter(service => service.id == this.service && service.has_selectable_location);
},
nonSelectableServices: function () {
return this.services.filter(service => service.id == this.service && !service.has_selectable_location);
},
selectableLocations: function () {
// Filter one more level down
return this.selectableServices.map(service => service.selectablelocations);
},
This is the JSON data structure I am working with as well (I cut it back to the relevant parts for this part of the code):
[
{
"id": 1,
"name": "Country Name",
"states": [
{
"id": 1,
"name": "State Name",
"services": [
{
"id": 1,
"name": "Service Name",
"has_selectable_location": 1,
"selectablelocations": [
{
"id": 1,
"name": "Selectable Location A",
},
]
}
]
}
]
}
]
Using a Vue plugin for Chrome I can see that the computed function selectableLocations loads an array containing the individual locations, but the existing v-for statement isn't able to function correctly. Instead I still need to go down one more level which I can do by adding an extra v-for loop like so:
<template v-for="selectableLocationsList in selectableLocations" >
<option v-for="sl in selectableLocationsList" :value="sl.location_id">{{sl.name}}</option>
</template>
Everything displays correctly, but I am not sure if this is best practice as I was hoping to do as much of this in a computed function as possible and ideally only require a single v-for statement. But if it's not possible like that I understand and I can leave it as is.
Thank you in advance.
Edit: After more testing and research I have come up with this code that works as I had desired:
var formArray = []
var locationsArray = this.servicesArray.filter(service => service.id == this.service);
locationsArray.map(service => service.selectablelocations);
locationsArray.forEach(function(selectableLocations) {
selectableLocations.selectablelocations.forEach(function(location) {
formArray.push(location)
});
});
return formArray;
Is there a way I can refactor this further and make it a bit cleaner?
Solely considering the code you posted after the Edit , the code can be refactored this way:
let formArray = [];
formArray = this.servicesArray
.filter(service => service.id == this.service)
.map(service => service.selectablelocations)
.reduce((prev, curr) => prev.concat(curr))
return formArray
Note that the map you used doesn't do anything as Array.prototype.map only returns a new array, but you didn't assign it to anything.

AngularJS select default option according to url

I have a dropdown menu that contains some links for various section of the page. The application is written with AngularJS version 1.4, the dropdown menu does works, but when I enter the page directly through the url in the dropdown menu is always selected the empty voice instead of the correct one. Here' the code:
HTML
<select ng-options="menu_voice.name for menu_voice in menu_voices track by menu_voice.url" ng-model='selectedOption' ng-change="changeLink()">
</select>
JS:
$scope.changeLink = function(){
$state.go($scope.selectedOption.url);
};
$scope.menu_voices = [
{
"url": 'account.company',
"name": 'Company'
},
{
"url": 'account.billing',
"name": 'Billing'
},
{
"url": 'account.password',
"name": 'Password'
},
{
"url": 'account.design',
"name": 'Design'
},
{
"url": 'account.social',
"name": 'Social'
},
{
"url": 'account.notifications',
"name": 'Notifications'
}
];
If I select a voice in the dropdown menu, I go to the correct link with the correct voice selected. But if in the url bar I enter something like:
www.myapp.com/account/billing
I go to the correct page but in the dropdown menu the selected voice is empty.
How can I solve this?
EDIT after first reply:
I added this:
var name = $window.location.pathname;
name = name.substring(9);
name = name.charAt(0).toUpperCase() + name.slice(1);
var url = $window.location.pathname.substring(1).replace(/\//g, '.');
$scope.getSelectedFromUrl = function(){
$scope.selectedOption = {"name": name, "url": url};
};
If I print in the console
console.log($scope.selectedOption);
I get the correct object, e.g:
Object {name: "Design", url: "account.design"}
In the html I simply added the ng-init:
<select ng-options="menu_voice.name for menu_voice in menu_voices track by menu_voice.url" ng-model='selectedOption' ng-change="changeLink()" ng-init="selectedOption = getSelectedFromUrl()">
</select>
But nothing changed.
You could use the ng-init directive to call a function that parses the route and matches it to an item from the voices array. Then set the selectedOption model to that array item, which will set the select option.
ng-init="selectedOption = getSelectedFromURL()"

Swapping data in Angular UI-Grid, new columns not visible when changing dataset externally

I've got a query tool I've been working on, which has an angular form that is filled out, and then when it's submitted it uses AJAX which returns JSON, which is then rendered into ui-grid, that JSON response looks like
{
"success": true,
"message": "",
"columns": ["first_name", "last_name", "company", "employed"]
"results": [
{first_name: "John", last_name: "Smith", company: "Abc Inc", employed: true},
{first_name: "Johnny", last_name: "Rocket", company: "Abc Inc", employed: true}]
}
I'm working on both the PHP and angular so I have full control over this JSON response if need be. I'm running into an issue when my JSON response from a first AJAX call is rendered, and then I run another, seperate AJAX call on the same page and get a new data set: this new data set does not render any of the columns that were not in the original data set. This is hugely problematic as the table is essentially cleared when none of the columns are the same, and I often need to load completely different data into ui-grid in this single page app.
When the JSON is recieved I simply bind the jsonResult.results to the old $scope.myData variable that ui-grid is bound to.
I've made a plunker isolating this issue. A dataset with a "punk" column is loaded, and then clicking "swap data" will try to load a dataset with "employee" column instead of "punk". I've so far looked into directives that will refresh or reload when the $scope.myData variable changes using $watch, and looked at finding something like $scope.columnDefs to let ui-grid know. Relatively new to angular and javascript so directives are still a bit over my head.
I have updated your plunker slightly:
$scope.swapData = function() {
if ($scope.gridOpts.data === data1) {
$scope.gridOpts.columnDefs = [
{ name:'firstName' },
{ name:'lastName' },
{ name:'company' },
{ name:'employee' }
];
$scope.gridOpts.data = data2;
//punk column changes to employee
}
else {
$scope.gridOpts.columnDefs = [
{ name:'firstName' },
{ name:'lastName' },
{ name:'company' },
{ name:'punk' }
];
$scope.gridOpts.data = data1;
//employee column changes to punk
}
};
http://plnkr.co/edit/OFt86knctJxcbtf2MwYI?p=preview
Since you have the columns in your json, it should be fairly easy to do.
One additional piece that I figured out with the help of Kevin Sage's answer and the plunker example... If you are using the backward-compatible "field" attribute the swapping does not work properly when there are field name overlaps between the two sets of column definitions. The column headers and the column widths are not rendered properly in this case. Using the "name" attribute of the column definition corrects this.
$scope.swapData = function() {
if ($scope.gridOpts.data === data1) {
$scope.gridOpts.columnDefs = [
{ field:'firstName' },
{ field:'lastName' },
{ field:'company' },
{ field:'employee' }
];
$scope.gridOpts.data = data2;
//punk column changes to employee
}
else {
$scope.gridOpts.columnDefs = [
{ field:'firstName' },
{ field:'lastName' },
{ field:'company' },
{ field:'punk' }
];
$scope.gridOpts.data = data1;
//employee column changes to punk
}
};
Example here: Plunker
My solution:
$http.get('url').success(function(res) {
// clear data
gridOptions.data.length = 0;
// update data in next digest
$timeout(function() {
gridOptions.data = res;
});
});

how to make view (form)from json using angular?

I am trying to make view from json .When I have array of objects .I am able to make view and validate that view .
If I have this array of object ,in that case I make able to view ,
check plunker
http://plnkr.co/edit/eD4OZ8nqETBACpSMQ7Tm?p=preview
[{
type: "email",
name: "email",
required:true
}, {
type: "text",
name: "name",
required:true
}, {
type: "number",
name: "phonenumber",
required:true
}, {
type: "checkbox",
name: "whant to check"
},
{
type: "url",
name: "server Url"
}];
Now the problem occurred when i have json object .I need to show view from json object .I don't know from where I will start work
I have this json
"displayName": display the name of label which is from of input text
field.
inputValues :represent the type of tmput filled .if it is number then
user fill only number , text then user only fill number ,email then
user fill email , if it switch then it is drop down with given
option.
"required" give if field is required or not ?
Assuming your JSON is coming from a configuration file or a service, you can start by obtaining the JSON as a JSON object:
angular.module('myapp', [])
.controller('MyController', ['$scope', function($scope) {
$scope.outputs = {};
$scope.rawInput = JSON.parse( '{"studentName": "abc", \
"input": {\
"loginUser": {\
"displayDetail": "UserId for login.",\
"displayName": "Login User Id*",\
"inputType": "TEXT",\
(I had to escape returns to allow the pretty printed JSON string to be parsed)
Once you have that, you are nearly there. Now you can just go the level of JSON that you require and construct your inputs array:
$scope.formInputs = $scope.rawInput['input'];
$scope.inputs = [];
angular.forEach($scope.formInputs, function(value, key) {
/* do something for all key: value pairs */
$scope.inputs.push({"type":value.inputType.toLowerCase(),"name":value.name,"required": value.required})
});
Note you should probably do some error checking here - for the purposes of this example, I don't use any. Here is a working plnkr that demonstrates this code.
I haven't got it all to work - you'll have to construct your select or radio button inputs, but I think you should be able to take it from here.
EDIT I have undated the plnkr to make it public

Categories

Resources