$.get($querystudent, function(response)
{
tbodystudent.empty();
console.log("Table TBODY Cleared!");
var students = response.result;
var $i = 0
$.each(students, function(_,student)
{
$i = student.ID
tbodystudent.append(
$("<tr>").append(
$("<td>").text(student.FirstName),
$("<td>").text(student.MiddleName),
$("<td>").text(student.LastName),
$("<td>").text(student.CourseID),
$("<td>").text(student.YearLevel),
$("<input></input>").attr({'type':'button','class':'button is-primary is-small','id':$i, 'onclick': select($i)}).val("Select")
),
);
});
}, "json");
This is my current Jquery code that appends data to the tbody with attribute onclick trying to call a function select(),
function select(x)
{
console.log('Im Here! ', x)
}
Without clicking any button, the console is showing that the three buttons have been clicked already from the start of the page Onload.
Console indicates that the function is called already with no buttons being clicked
Inspect also indicates that the onclick attribute was not added to the button attributes
Based on your idea, I've updated and let it works. You can check the below demo:
'onclick': select($i) -> 'onclick': 'select(' + $i + ')'
$("<input></input>") -> $("<button>") : I'm still finding the reason why $("<input>") is not working
const students = [{
ID: 1,
FirstName: 'A',
MiddleName: 'B',
LastName: 'C',
CourseID: 1,
YearLevel: 1
},
{
ID: 2,
FirstName: 'A',
MiddleName: 'B',
LastName: 'C',
CourseID: 1,
YearLevel: 1
}, {
ID: 3,
FirstName: 'A',
MiddleName: 'B',
LastName: 'C',
CourseID: 1,
YearLevel: 1
}
]
function select(x) {
console.log('Im Here! ', x)
}
$.each(students, function(_, student) {
$i = student.ID
$('#tbodystudent').append(
$("<tr>").append(
$("<td>").text(student.FirstName),
$("<td>").text(student.MiddleName),
$("<td>").text(student.LastName),
$("<td>").text(student.CourseID),
$("<td>").text(student.YearLevel),
$("<button>").attr({
'type': 'button',
'class': 'button is-primary is-small',
'id': $i,
'onclick': 'select(' + $i + ')'
}).text("Select")
),
);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table">
<thead>
<tr>
<th scope="col">FirstName</th>
<th scope="col">MiddleName</th>
<th scope="col">LastName</th>
<th scope="col">CourseID</th>
<th scope="col">YearLevel</th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="tbodystudent">
</tbody>
</table>
Related
preview image
https://angular-table-tree-example-md58kf.stackblitz.io
Good morning, could someone help me to know how I can obtain the selected rows with the radio button, the table is with a tree, I attach the code in the following link:
https://stackblitz.com/edit/angular-table-tree-example-md58kf?file=app/table-basic-example.ts
ps: i am using google translate
this is the code i tried to do
HTML
<table mat-table [dataSource]="dataSourceTree" class="mat-elevation-z8">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>
<span [style.paddingLeft.px]="40"> Name </span>
</th>
<td mat-cell *matCellDef="let data">
<div
*ngIf="data.group"
[style.marginLeft.px]="data.level * 20"
style="display: inline"
>
<mat-radio-button
class="example-radio-button"
[checked]="data.selected"
[name]="data.group"
[value]="data"
>
</mat-radio-button>
</div>
{{data.name}}
</td>
</ng-container>
<ng-container matColumnDef="count">
<th mat-header-cell *matHeaderCellDef>Code</th>
<td mat-cell *matCellDef="let data">
<div
*ngIf="data.group"
[style.marginLeft.px]="data.level * 20"
style="display: inline"
></div>
{{data.count}}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<button (click)="getSelected()">show items selected</button>
TYPESCRIPT
import { FlatTreeControl } from '#angular/cdk/tree';
import { Component } from '#angular/core';
import {
MatTreeFlatDataSource,
MatTreeFlattener,
} from '#angular/material/tree';
interface FoodNode {
name: string;
count?: number;
children?: FoodNode[];
group?: number;
selected?: boolean;
expandable?: boolean;
level?: number;
}
const TREE_DATA: FoodNode[] = [
{
name: 'Math',
count: 11,
children: [
{ name: 'MAT1A', count: 10, group: 1 },
{ name: 'MAT1B', count: 20, group: 1 },
{ name: 'MAT1C', count: 30, group: 1 },
],
},
{
name: 'Physical',
count: 22,
children: [
{ name: 'FIS1A', count: 40, group: 2 },
{ name: 'FIS1B', count: 50, group: 2 },
{ name: 'FIS1C', count: 60, group: 2 },
],
},
];
/**
* #title Basic use of `<table mat-table>`
*/
#Component({
selector: 'table-basic-example',
styleUrls: ['table-basic-example.css'],
templateUrl: 'table-basic-example.html',
})
export class TableBasicExample {
displayedColumns: string[] = ['name', 'count'];
private transformer = (node: FoodNode, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
count: node.count,
level: level,
group: node.group,
FoodNode: node.children,
selected: node.selected,
};
};
treeControl = new FlatTreeControl<FoodNode>(
(node) => node.level,
(node) => node.expandable
);
treeFlattener = new MatTreeFlattener(
this.transformer,
(node) => node.level,
(node) => node.expandable,
(node) => node.children
);
dataSourceTree = new MatTreeFlatDataSource(
this.treeControl,
this.treeFlattener
);
constructor() {
this.dataSourceTree.data = TREE_DATA;
this.treeControl.expandAll();
}
hasChild = (_: number, node: FoodNode) => node.expandable;
getSelected() {
let result = [];
this.dataSourceTree.data.forEach((node) => {
result = result.concat(
this.treeControl.getDescendants(node).filter((x) => x.selected)
);
console.log(node);
});
console.log(result);
}
}
You can add mat-radio-group for each element in the array TREE_DATA, then use [(ngModel)] to bind the selected item to a member in that array as following:
<mat-radio-group [(ngModel)]="data.selectedItem">
Here is a full solution for inspiration:
https://stackblitz.com/edit/angular-ivy-ycnz1d?file=src/app/app.component.html
I have an array of users that contains objects for each user with full name, id, role, etc. Said users have a paramater: user_machines that it's array filled with objects in itself, and i want to get & display specific values from each object of this array. More specifically, it goes like this:
I display all users, and if the user has user_machines array with objects in it, i want to display for example the machine_name of said object.
At this time, my query looks like this:
class UserController extends Controller
{
public function index()
{
$users = User::with('userMachines')->get();
return response()->json(
[
'status' => 'success',
'users' => $users->toArray()
],
200
);
}
It get's all the information i need, but i dont know how to sort it.
Here's my getUsers mixin:
export const getUsers = {
methods: {
getUsers() {
axios
.get("users")
.then(res => {
this.users = res.data.users;
})
.catch(err => {
console.log(err);
});
}
}
};
And here's my initialization method:
methods: {
initialize() {
this.users = [
{
id: "",
full_name: "",
username: "",
role: "",
division: "",
center: "",
machines: "",
user_machines: []
}
];
},
Here's the Data Table:
<v-data-table
:headers="headers"
:items="users"
:key="users.id"
:search="search || radio"
hide-actions
class="elevation-1"
>
<template v-slot:items="props">
<td class="text-xs-left">
<v-avatar :size="30" color="grey lighten-4">
<img :src="avatar">
</v-avatar>
</td>
<td class="text-xs-left">{{ props.item.full_name }}</td>
<td class="text-xs-left">{{ props.item.role }}</td>
<td class="text-xs-left">{{ props.item.division }}</td>
<td class="text-xs-left">{{ props.item.center }}</td>
<td class="text-xs-left">{{ props.item.user_machines }}</td>
<td class="justify-right layout ml-3">
<v-spacer></v-spacer>
<v-btn color="#009af9" flat #click="editItem(props.item)">ВИЖ</v-btn>
</td>
</template>
<template v-slot:footer>
<td :colspan="headers.length">
<v-btn color="#009af9" class="getMoreButton" large dark>GET MORE</v-btn>
</td>
</template>
<template v-slot:no-data>
<v-alert
:value="true"
color="error"
icon="warning"
>Sorry, nothing to display here :(</v-alert>
<v-btn color="#009af9" #click="initialize">Reset</v-btn>
</template>
</v-data-table>
Here's how it looks in a get request in Telescope:
users: [
{
id: 1,
full_name: "SomeDude",
username: "SomeDude",
role: "admin",
division: "asdf",
center: "asdf",
created_at: "2019-05-25 10:24:17",
updated_at: "2019-05-25 10:24:17",
user_machines: [
{
id: 1,
machine_number: 2143,
machine_name: "FirstMachine",
machine_division: "FirstMachine"",
machine_center: "FirstMachine"",
machine_speed: "FirstMachine"",
created_at: "2019-05-25 10:24:17",
updated_at: "2019-05-25 10:24:17",
pivot: {
user_id: 1,
machine_id: 1
}
},
{
id: 2,
machine_number: 2241,
machine_name: "SecondMachine",
machine_division: "SecondMachine",
machine_center: "SecondMachine",
machine_speed: "SecondMachine",
created_at: "2019-05-25 10:24:17",
updated_at: "2019-05-25 10:24:17",
pivot: {
user_id: 1,
machine_id: 2
}
},
{
id: 3,
machine_number: 2341,
machine_name: "ThirdMachine",
machine_division: "ThirdMachine",
machine_center: "ThirdMachine",
machine_speed: "ThirdMachine",
created_at: "2019-05-25 10:24:17",
updated_at: "2019-05-25 10:24:17",
pivot: {
user_id: 1,
machine_id: 3
}
}
I would really appreciate some help and some directions on what to read on the subject from more expirienced developers.
I'm using Laravel, Vue, MySQL.
Thanks in advance!
If you only want to display the machine_name then you'll either need to loop through them using v-for:
replace
<td class="text-xs-left">{{ props.item.user_machines[0].machine_name }}</td>
with
<td class="text-xs-left">
<ul>
<li v-for="user_machine in props.item.user_machines" v-text="user_machine.machine_name"></li>
</ul>
</td>
Obviously you can use different markup instead of the unordered list (</ul>) if you want to.
Or if you're only wanting to display the first one then you could do something like:
<td class="text-xs-left">{{ props.item.user_machines[0].machine_name }}</td>
I'm trying to search user by their email id. This partially works. If I search users for the first time by entering a email and clicking search button, it works. But then if I search of another user, its searches filters automatically without pressing the search button.
I should be able to search user only after I click the search button. Thanks in advance
var myApp = angular.module("myApp", []);
myApp.controller("myController", function($scope) {
console.log("in controller...");
$scope.newUser = {};
$scope.info = "";
// Users array list
if (localStorage.getItem("users") === null) {
$scope.users = [{
email: "Vai#yahoo.com",
password: "Sha123",
firstName: "Vai",
lastName: "LSha",
contact: "123-223-8989",
role: "Super-Admin",
company: ""
},
{
email: "John#yahoo.com",
password: "John123",
firstName: "John",
lastName: "Doe",
contact: "281-283-2480",
role: "Supplier-Admin",
company: "Apple"
},
{
email: "Rick#yahoo.com",
password: "Rick123",
firstName: "Rick",
lastName: "Fraiser",
contact: "987-283-2489",
role: "Supplier-User",
company: "Apple"
},
{
email: "Reek#yahoo.com",
password: "Reek123",
firstName: "Reek",
lastName: "Phaine",
contact: "876-277-2289",
role: "Supplier-User",
company: "Apple"
},
{
email: "Jim#yahoo.com",
password: "Jim123",
firstName: "Jim",
lastName: "Jones",
contact: "487-283-2489",
role: "Supplier-User",
company: "Apple"
}
];
localStorage.setItem("users", JSON.stringify($scope.users));
} else {
$scope.users = JSON.parse(localStorage.getItem("users"));
}
//Deleting a user.
$scope.deleteUser = function(user) {
$scope.clickedUser = user;
console.log($scope.users.indexOf($scope.clickedUser));
$scope.users.splice($scope.users.indexOf($scope.clickedUser), 1);
localStorage.setItem("users", JSON.stringify($scope.users));
$scope.info = "User Deleted Successfully!";
};
$scope.clearInfo = function() {
$scope.user = "";
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>User Management- M&M</title>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="js/userApp.js"></script>
</head>
<body ng-app="myApp" ng-controller="myController">
<div>
<input type="text" placeholder="Search Users" ng-model="searchUsers.email">
<button ng-click="search = searchUsers" type="button">Search</button>
</div>
<hr>
<table border="1">
<thead>
<tr class="table100-head">
<th>Email</th>
<th>First Name</th>
<th>Last Name</th>
<th>Contact</th>
<th>Role</th>
<th>Company</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users | filter: {'email':search.email} track by $index">
<td>{{user.email}}</td>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.contact}}</td>
<td>{{user.role}}</td>
<td>{{user.company}}</td>
<td>
<button ng-click="deleteUser(user)" type="button">Delete</button>
</td>
</tr>
</tbody>
</table>
</body>
</html>
In first attempt your search.email was undefined, and when you clicked on search your search.email got defined, so next time on wards when you type something the default two way data binding was triggering the search.
In the below code snippet I have added a new function
$scope.searchUser = function(userEmail){
$scope.searchEmail = userEmail
}
and only when the user clicks on the button I am actually binding with the $scope which is triggering the search. Also added an onChange event where if the user erase up the text it resets the search
var myApp = angular.module("myApp", []);
myApp.controller("myController", function($scope) {
console.log("in controller...");
$scope.newUser = {};
$scope.info = "";
// Users array list
$scope.users = [{
email: "Vai#yahoo.com",
password: "Sha123",
firstName: "Vai",
lastName: "LSha",
contact: "123-223-8989",
role: "Super-Admin",
company: ""
},
{
email: "John#yahoo.com",
password: "John123",
firstName: "John",
lastName: "Doe",
contact: "281-283-2480",
role: "Supplier-Admin",
company: "Apple"
},
{
email: "Rick#yahoo.com",
password: "Rick123",
firstName: "Rick",
lastName: "Fraiser",
contact: "987-283-2489",
role: "Supplier-User",
company: "Apple"
},
{
email: "Reek#yahoo.com",
password: "Reek123",
firstName: "Reek",
lastName: "Phaine",
contact: "876-277-2289",
role: "Supplier-User",
company: "Apple"
},
{
email: "Jim#yahoo.com",
password: "Jim123",
firstName: "Jim",
lastName: "Jones",
contact: "487-283-2489",
role: "Supplier-User",
company: "Apple"
}
];
//Deleting a user.
$scope.deleteUser = function(user) {
$scope.clickedUser = user;
console.log($scope.users.indexOf($scope.clickedUser));
$scope.users.splice($scope.users.indexOf($scope.clickedUser), 1);
localStorage.setItem("users", JSON.stringify($scope.users));
$scope.info = "User Deleted Successfully!";
};
$scope.clearInfo = function() {
$scope.user = "";
};
$scope.searchUser = function(userEmail){
$scope.searchEmail = userEmail
}
$scope.onChange = function(){
if($scope.email.length === 0){
$scope.searchEmail = "";
$scope.email = "";
}
}
});
<html lang="en">
<head>
<meta charset="utf-8">
<title>User Management- M&M</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myController">
<div>
<input type="text" placeholder="Search Users" ng-change="onChange()" ng-model="email">
<button ng-click="searchUser(email)" type="button">Search</button>
</div>
<hr>
<table border="1">
<thead>
<tr class="table100-head">
<th>Email</th>
<th>First Name</th>
<th>Last Name</th>
<th>Contact</th>
<th>Role</th>
<th>Company</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users | filter: {'email': searchEmail} track by $index">
<td>{{user.email}}</td>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
<td>{{user.contact}}</td>
<td>{{user.role}}</td>
<td>{{user.company}}</td>
<td>
<button ng-click="deleteUser(user)" type="button">Delete</button>
</td>
</tr>
</tbody>
</table>
</body>
</html>
I was using buefy <b-autocomplete> component and there is one property called v-model which is binding values to the input field
now I wanna bind Full Name into the field but the data consist with list[index].first_name and list[index].last_name, and the index is from a v-for loop.
Since v-model cannot bind a function (it has specific index so I cannot just concat it on computed then pass it on) so it's either v-model="list[index].first_name" or v-model="list[index].last_name"
How do I make it bind's these two?
You need a settable computed for full name, and you can v-model that. You just have to decide on a rule for where extra spaces go and what to do if there is no space.
new Vue({
el: '#app',
data: {
firstName: 'Joe',
lastName: 'Smith'
},
computed: {
fullName: {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(newValue) {
const m = newValue.match(/(\S*)\s+(.*)/);
this.firstName = m[1];
this.lastName = m[2];
}
}
}
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
First: {{firstName}}<br>
Last: {{lastName}}<br>
Full Name: <input v-model="fullName">
</div>
I am not sure if i get the question,but i am assuming that you have a list of names and last names and you want to give the ability to user to change those proprties of list.For more See the example in action
The "html" part
<div id="app">
<template v-for="item in list" :key="list.id">
<input type="text" :value="item.name" #input="changeList($event, item.id, 'name')">
<input type="text" :value="item.last_name" #input="changeList($event, item.id, 'last-name')">
Your full name is {{item.name}} {{item.last_name}}
<hr>
</template>
</div>
The "javascript(vue)" part
new Vue({
el: "#app",
data: {
list: [
{ id: 1, name: "name1", last_name: 'last_name 1' },
{ id: 2, name: "name2", last_name: 'last_name 2' },
{ id: 3, name: "name3", last_name: 'last_name 3' },
{ id: 4, name: "name4", last_name: 'last_name 4' }
]
},
methods: {
changeList(event, id, property) {
let value = event.target.value
for (item of this.list) {
if (item.id === id) {
if(property === 'name') {
item.name = value
}else if (property === 'last-name') {
item.last_name = value
}
}
}
}
}
})
As it's been said you can't use 2 values in v-model
But if you want to use <b-autocomplete> that means you already have the data and you can compute it in any way you want.
If you have an array of user objects (with firstname and lastname for example) you can do something like:
data() {
return {
users: [
//...
],
computedUsers: [],
}
},
mounted() {
this.users.forEach(user => {
this.computedUsers.push(user.firstname + ' ' + user.lastname)
})
}
and use this new array in the filteredDataArray (from the Buefy autocomplete example)
Fiddle example here
I am new in knockout. I want to make the list of students.
I have attached the list structure which returned from MVC as an image, Click here to view.
Js code:
var employeeListViewModel = {};
var employeeViewModel = {
id: "",
name: ko.observable("neenu"),
age: ko.observable(),
email: ko.observable(),
department: ko.observable(),
address: {
address1: ko.observable(),
city: ko.observable(),
State: ko.observable()
},
};
var employeePageViewModel = {
employee: employeeViewModel,
employees: employeeListViewModel
};
var dataSource = {
getemployees: function () {
getData("Employee/GetEmployees").then((data) => {
var result = ko.mapping.fromJS(data.data);
employeeListViewModel = result();
console.log(employeeListViewModel);
});
},
init: function () {
this.getemployees();
}
}.init();
ko.applyBindings(employeePageViewModel);
Html code:
<thead>
<tr>
<th>First name</th>
<th>Last name</th>
</tr>
</thead>
<tbody data-bind="foreach: employees">
<tr>
<td data-bind="text: Name"></td>
<td data-bind="text: Id"></td>
</tr>
</tbody>
When I run this page ,It is neither displaying any error nor displaying data. Please help.
1) employeeListViewModel must be a ko.observableArray()
2) also when getting the result from your getData function just set the observableArray to the list:
employeeListViewModel(data.data); //assuming data.data is a [].
3) ko.mapping.fromJS(data.data); can be removed