HOW TO select where index LARAVEL API JSON - json

How to echo the second array value where the array index of Json is same as the clicked select option?
what i need is, when i select the select option that has subject value : Webinar 1, then the will show the total_participation : 100
The API Json
{
"status": 200,
"message": "success",
"data": {
"records": [
{
"subject": "Webinar 1",
"total_participant": 100
},
{
"subject": "Webinar 2",
"total_participant": 165
},
{
"subject": "Webinar 3",
"total_participant": 143
}
]
},
"error": []
}
MY CONTROLLER :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Utils\Endpoints\WebinarEndpoints;
use Illuminate\Support\Facades\Http;
class WebinarController extends Controller
{
public $webinarEndpoints;
function __construct(){
$this->webinarEndpoints = new WebinarEndpoints;
}
public function index(){
$result = $this->webinarEndpoints->participant()->json();
$webinarlist = $this->webinarEndpoints->webinarlist()->json();
switch ($result['status']) {
case '200':
return view('webinar', [
'participants' => $result['data']['records'],
'lists' => $webinarlist['data']['records']
]);
break;
default :
break;
}
}
}
VIEW :
<div class="col-3">
<select class="form-control">
#foreach ($lists as $list)
<option onclick="total()">{{$list['subject']}} </option>
#endforeach
</select>
</div>
<h3> {{ GET total_participant based on Selected select option index }} </h3>
THANKS FOR HELPING ME!!

a simple way to deal with this could be to give the total_participant to your total() function :
<div class="col-3">
<select class="form-control">
#foreach ($lists as $list)
<option onclick="total({{$list['total_participant']}})">{{$list['subject']}} </option>
#endforeach
</select>
</div>
<h3> {{ GET total_participant based on Selected select option index }} </h3>

Related

Separate values in select containing 2 object

My contains 2 different objects, obj1 and obj2.
<select multiple class="full-width" style="min-height: 200px" ng-model="vm.obj1" >
<optgroup label="First obj">
<option ng-repeat="item in vm.obj1" >{{item.valeur}}</option>
</optgroup>
<optgroup label="Second obj">
<option ng-repeat="item in vm.obj2">{{item.libelle}}</option>
</optgroup>
</select>
obj1 = {[
0: {valeur: non},
1: {valeur: oui}
]}
obj2 = {[
0: {libelle: instance},
]}
What I get when I select values :
What I actually want :
I want the values to be in separated arrays since they are both from different objects so 1 array with ['oui','non'] and the second array with ['instance']. How can I do that ?
Visual of the dropdown ( sorry for the big blue lines I wanted to stay on the point with the datas I made in the question )
You can use ngChange to respond to any changes to the ngModel value and store that in a new property:
function ctrl($scope) {
$scope.options = [{
name: "A",
options: ["A1", "A2"]
},
{
name: "B",
options: ["B1", "B2"]
},
];
$scope.parseSelection = function() {
const selected = {};
// Loop over the selected options and check from which group they came
$scope.rawSelected.forEach((value) => {
$scope.options.forEach(({ name, options }) => {
if (options.includes(value)) {
// The option comes from the current group
if (!selected[name]) {
selected[name] = [];
}
selected[name].push(value);
}
});
});
$scope.selected = selected;
};
}
angular.module("app", [])
.controller("ctrl", ctrl)
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select multiple ng-model="rawSelected" ng-change="parseSelection()">
<optgroup ng-repeat="group in options" label="group.name">
<option ng-repeat="option in group.options">{{option}}</option>
</optgroup>
</select>
{{rawSelected}} - {{selected}}
</div>

Angular table filter clearing group

I have 2 filters on a user list. A user can select a group containing members and use the search filter to search by last name. When the user backspaces a user to look for another, this resets the groups to all users. I need this to only show the users in the selected group.
TS
updateFilter(event) {
const val = event.target.value.toLowerCase();
const temp = this.temp.filter(function (d) {
return d.lastName.toLowerCase().indexOf(val) !== -1 || !val;
});
this.rows = temp;
if (this.table) {
this.table.offset = 0;
}
}
onGroupSelected($event) {
const groupId = $event.target ? $event.target.value : $event;
if (groupId === 'none') {
this.rows = this.temp;
} else {
const groupUsers = this.groupUserMap.get(groupId);
if (groupUsers) {
this.rows = this.temp.filter((serviceUser) =>
groupUsers.includes(serviceUser.id));
} else {
this.rows = [];
}
}
// #ts-ignore
this.userSelections = this.userSelections ? this.userSelections : {};
this.userSelections.groupId = groupId;
localForage.setItem(this.username, this.userSelections);
}
HTML
<input
type='text'
class="form-control w-200px"
placeholder='Search by Last Name...'
(keyup)='updateFilter($event)'
/>
<select class="form-control w-200px" (change)="onGroupSelected($event)">
<option value="none">All service users</option>
<option *ngFor="let group of groups"
[value]="group.id"
[selected]="userSelections.groupId === group.id">
{{group.name}}
</option>
</select>
You can use ngModel with tow-way binding, to save and manipulate search filters:
<select
class="form-control w-200px"
[(ngModel)]="selectedGroup"
(change)="onGroupSelected()"
>
<option value="none">All service users</option>
<option *ngFor="let group of groups" [value]="group.id">
{{ group.name }}
</option>
</select>
<input
type="text"
class="form-control w-200px"
placeholder="Search by Last Name..."
[(ngModel)]="search"
(keyup)="updateFilter()"
/>
And in order not to lose your users table you can create a copy which will be filtered and displayed.
public initialUsers = [
{ id: 100, groupId: 1, name: 'foo' },
{ id: 101, groupId: 2, name: 'bar' },
{ id: 102, groupId: 1, name: 'john' },
{ id: 103, groupId: 2, name: 'doe' },
{ id: 104, groupId: 2, name: 'baaar' },
{ id: 105, groupId: 1, name: 'fooodoe' },
];
public filteredUsers = [];
ngOnInit(): void {
this.filteredUsers = this.initialUsers;
}
Here is a demo on stackblitz, I used a list to go fast but It's just display. You just have to replace <ul> <li></li> </ul> by your <table> ... </table>
If you would want to take an observable way of doing this, then I would suggest to make a form of your controls, ooooor just use 2 form controls instead. I chose form here as it wraps it up nicely with both form controls (search and dropdown):
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
search: [''],
group: [0] // "all" option as initial id
})
}
Then we would listen to when the form value changes and assign the filtered data to a variable, here named filteredUsers$.
this.filteredUsers$ = this.form.valueChanges.pipe(
startWith(this.form.value), // to trigger initially
// 'this.users' refers to your original users array
map((value: any) => {
// 'all' option is chosen, just filter based on search
if (value.group === 0) return this.users.filter(x => x.lastName.toLowerCase().includes(value.search))
// filter by group and search
return this.users.filter(x => {
return (x.groupId === value.group) && (x.lastName.toLowerCase().includes(value.search.toLowerCase()))
})
})
)
That is it, then we just iterate filteredUsers$ in the template:
<tr *ngFor="let user of filteredUsers$ | async">
Of course we need the form in the view and it would look like this:
<form [formGroup]="form">
<input
type="text"
placeholder="Search by Last Name..."
formControlName="search"
/>
<select formControlName="group">
<option *ngFor="let group of groups" [ngValue]="group.id">
{{ group.name }}
</option>
</select>
</form>
Here is a DEMO with the above code

Populate select options based on another select with Vue and JSON

Need help creating a dynamic search form with select options for Districts, Regions and locations.
Regions select must be populated based on the District and Locations based on the Regions
The data is stored on a JSON file with the following structure:
[
{
"level": 1,
"code": 1,
"name": "District"
},
{
"level": 2,
"code": 101,
"name": "Region"
},
{
"level": 3,
"code": 10101,
"name": "Location"
}
]
here´s the complete JSON file:
https://gist.github.com/tomahock/a6c07dd255d04499d8336237e35a4827
html snippet
<select name="district" v-model="district">
<option value=''>Select District</option>
<option v-for="district in filterDistricts" :value="district.code">
{{ district.name }}
</option>
</select>
<select name="region" v-model="region">
<option value=''>Select Region</option>
<option v-for="region in filterRegions" :value="region.code">
{{ region.name }}
</option>
</select>
<select name="location" v-model="location">
<option value=''>Select Location</option>
<option v-for="location in filterLocations" :value="location.code">
{{ location.name }}
</option>
</select>
javascript snippet
data() {
return {
searchData: [],
districts: [],
regions: [],
locations: []
}
},
created(){
this.fetchData();
},
computed: {
filterDistricts() {
return this.districts = this.searchData.map(res => ({
level: res.level,
code: res.code,
name: res.name
}))
.filter( res => res.level === 1)
},
filterRegions() {
return this.regions = this.searchData.map(res => ({
level: res.level,
code: res.code,
name: res.name
}))
.filter( res => res.level === 2)
},
filterLocations() {
return this.locations = this.searchData.map(res => ({
level: res.level,
code: res.code,
name: res.name
}))
.filter( res => res.level === 3)
}
},
methods: {
fetchData(){
axios.get('http://localhost:8000/json/searchData.json')
.then((response) => (
this.searchData = response.data
))
.catch((err) => {
console.log(err)
})
}
}
I think I need to associate de code numbers, but I can´t figure out how.
Any ideas?
Thanks
First, I wouldn't bother with those map calls since you're only reproducing the same structure.
Second, I'll assume that each sub-element (region / location) relates to its parent (district / region) via a pattern where each sub's code is prefixed with the parent code, followed by a two-digits, zero-padded.
With that in mind, try this in your computed properties
filterDistricts () {
return this.searchData.filter(({ level }) => level === 1)
},
filterRegions () {
// assuming you don't want any selections until a district is chosen
if (!this.district) return []
const codeCheck = new RegExp(`^${this.district}\\d{2}$`)
return this.searchData.filter(({ level, code }) =>
level === 2 && codeCheck.test(code))
},
filterLocations () {
if (!this.region) return []
const codeCheck = new RegExp(`^${this.region}\\d{2}$`)
return this.searchData.filter(({ level, code }) =>
level === 3 && codeCheck.test(code))
}
Extra notes...
From looking at your template, it seems you should initialise your data as
data () {
return {
searchData: [],
district: null,
region: null,
location: null
}
}
Computed properties don't need to be stored in data properties so you don't need districts, regions and locations.
Your label options should also be disabled so they cannot be selected, eg
<option disabled value="">Select Region</option>

How to solve Angular [object object] in template

I am getting [object object] showing in my html page.
I am calling the a web service and in my console.log. I can see the full response but on my template I only see [object object]
test() {
this.http.post('api...', JSON.stringify(this.getAllCaseInfoWithCAS)).subscribe(data => {
this.testData = [data];
});
}
I have a ngFor
<ng-template ngbPanelContent>
<div class="row" *ngFor="let item of testData">
{{item.getAllCaseInfoWithCASReturn.caseDetails}}
</div>
</ng-template>
The response looks like this
{
"getAllCaseInfoWithCASReturn": {
"caseDetails": {
"caseNumber": "12345",
"componentDetails": {
"component": "29"
},
"personNumber": "5",
"month": "7"
}
}
}
How can I display all the information on the template?
You can use JsonPipe
{{ value_expression | json }}
Converts a value into its JSON-format representation. Useful for debugging.
{{ item.getAllCaseInfoWithCASReturn.caseDetails | json }}
Better start by making JSON formatted as an array of caseDetails, here is a rough code of what you can do with current JSON:
// This should be refactored to a service file.
getCaseDetails(data: any): Observable<any[]> {
const url = `api/url`;
return this.httpClient.post(url, data)
.pipe(
map(result => result['getAllCaseInfoWithCASReturn']['caseDetails']),
tap(caseDetail => console.log(caseDetail))
)
}
test() {
this.getCaseDetails(dummyData).subscribe(caseDetail => {
this.testData = caseDetail;
})
}
<ng-template ngbPanelContent>
<div class="row">
{{testData?.caseNumber}} <!-- or json pipe -->
{{testData?.personNumber}}
{{testData?.month}}
{{testData?.componentDetails?.component}}
</div>
</ng-template>

vuejs axios data not populated [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
While the VueJS data that is populated from Axios Get method and can be confirmed by outputting the data into console, I am not able to access the data from the front end.
Here is my sample JSON ouput
{
"locations" : {
"items" : ["abc","def","ghi"],
"selectedLocation" : ""
},
"categories" : {
"items" : {
"doctor" : ["test", "test2", "test3"],
"management" : ["test1","test2","test3"]
},
"subcategories":[],
"selectedCategory":"",
"selectedSubCategory":""
}
Here is my Front End Code
<form id="vueAppJobSearchPanel" class="offset-top-10 offset-sm-top-30" action="/job-search">
<div class="group-sm group-top">
<div style="max-width: 230px;" class="group-item element-fullwidth">
<div class="form-group">
<select v-model="locations.selectedLocation" id="form-filter-location" name="loc" data-minimum-results-for-search="Infinity" class="form-control">
<option value="">{{global.job_search_panel.placeholder_title_location}}</option>
<option v-for="location in locations.items" :value="location">${location}</option>
</select>
</div>
</div>
<div style="max-width: 230px;" class="group-item element-fullwidth">
<div class="form-group">
<select v-model="categories.selectedCategory" id="form-filter-location" name="cat" data-minimum-results-for-search="Infinity" class="form-control">
<option value="">{{global.job_search_panel.placeholder_title_category}}</option>
<option v-for="(category_obj, category) in categories.items" :value="category">${category}</option>
</select>
</div>
</div>
</div></form>
Here is my VueJS and AXIOS code
const vm = new Vue({
el: '#vueAppJobSearchPanel',
delimiters: ['${', '}'],
data: {
test: {
"items" : ["abc","def","ghi"],
"selectedLocation" : ""
},
locations : {},
categories : {}
},
mounted(){
this.loadDropDown();
},
methods: {
loadDropDown : function() {
let modelName = "CustomModule1";
let apiUrl = '/api/' + modelName + '/getFields';
axios.get(apiUrl)
.then(function (response) {
this.locations = constructLocationDropDownValues(response, modelName);
this.categories = constructCategorySubCategoryDropDownValues(response, modelName);
})
.catch(function (error) {
console.log(error);
});
}
}});
this.locations inside the loadDropDown function return a valid JSON. However the JSON is not passed to the front end (i.e. HTML). When I tried to output "locations" it will return an empty {}
Ideas? Thank you
The problem is with 'this' inside the axios callback. You should use arrow function to keep the context
axios
.get(apiUrl)
.then(response => {
this.locations = constructLocationDropDownValues(response, modelName)
this.categories = constructCategorySubCategoryDropDownValues(response,modelName)
})
.catch(function (error) {
console.log(error)
})