I display a list by using the v-repeat directive.
http://jsfiddle.net/ftc9ev7p/1/
Please notice the dynamically created argument of the v-el directive, which is made of
v-el="inputField{{task.id}}"
or alternatively
v-el="{{'inputField' + task.id }}"
Still it doesn't get recognized, since I get:
Uncaught TypeError: Cannot read property 'focus' of undefined
I want to click the edit button and have the according input field focused on.
A similar syntax works, when I dynamically add a css class. Just uncomment the line with the .focus() and click "edit".
new Vue({
el: '#tasks',
data: {
"tasks": [{
"id": 25,
"body": "Slack Noooo Yes",
"completed": true,
"created_at": "2015-08-05 17:00:26",
"updated_at": "2015-08-05 17:00:26"
}, {
"id": 27,
"body": "And",
"completed": false,
"created_at": "2015-08-05 17:22:14",
"updated_at": "2015-08-05 17:22:14"
}, {
"id": 28,
"body": "Happiness",
"completed": false,
"created_at": "2015-08-05 17:22:16",
"updated_at": "2015-08-05 17:22:16"
}, {
"id": 29,
"body": "Love",
"completed": true,
"created_at": "2015-08-06 07:45:02",
"updated_at": "2015-08-06 07:45:02"
}],
newTask: ''
},
methods: {
editTask: function(task) {
var inputField = 'inputField' + task.id;
alert(inputField);
var self = this;
self.$$.inputField.focus();
document.querySelector(".task" + task.id).className += " edit";
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.8/vue.min.js"></script>
<table class="table" id="tasks">
<thead>
<tr>
<th>Task</th>
<th>Edit</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr v-repeat="task: tasks">
<td class="todo">
<span class="task{{ task.id }}" v-on="dblclick: editTask(task)">
{{ task.body }}
</span>
</td>
<td>
<input type="text" class="editInputField" v-el="inputField{{ task.id }}" value="{{ task.body }}" v-on="keyup:editTask(task) | key 'enter'">
</td>
<td>
<button class="btn btn-xs btn-primary" v-on="click: editTask(task)">Edit</button>
</td>
</tr>
</tbody>
</table>
Here is the jsfiddle:
http://jsfiddle.net/ftc9ev7p/1/
You don't really have to number the elements by v-el since you can get a child ViewModel created by v-repeat. The official guide is on http://vuejs.org/guide/events.html#Invoke_Handler_with_Expression.
You can pass this to editTask in v-on and then you can get the child ViewModel by the first argument:
<div v-repeat="task: tasks">
<span class="task" v-el="label" v-on="dblclick: editTask(this)">
<input type="text" v-el="inputField" class="editInputField" value="{{ task.body }}">
</div>
editTask: function (task) {
task.$$.inputField.focus();
task.$$.label.className += " edit";
}
Also you can get the targetVM by using event.targetVM in the function without the need of passing this to your function.
<div v-repeat="task: tasks">
<span class="task" v-el="label" v-on="dblclick: editTask()">
<input type="text" v-el="inputField" class="editInputField" value="{{ task.body }}">
</div>
editTask: function () {
event.targetVM.$$.inputField.focus();
event.targetVM.$$.label.className += " edit";
}
JS Fiddle: http://jsfiddle.net/n1ef18uq/1/
Related
I have implemented a custom Previous, Next functionality using angular 8. What this functionality does is, when i click on previous then it shows the results based matching the url routing. As i am getting the data from back end in the below format.
[
{
"id": "8a80800e6bd1733c016bd1b2c29b3f73",
"suggestionId": "tBAKv6Dh",
"projectId": "8a80800e6bd1733c016bd1b165d63d91",
"category": "Unsecured",
"severity": "Major",
"status": "NEW",
"issues": [
{
"autoSuggestionId": null,
"issueId": "NiEQOTRlELcsXFbDSQjm",
"jobId": "8a8080966bda207d016bda614f5d2a48",
"status": "open",
"runId": null,
"jobName": "Dev",
"envName": "Master"
}
],
},
{
"id": "8a80800e6bd1733c016bd1b2cb8e4018",
"suggestionId": "tBAKv6Dh",
"projectId": "8a80800e6bd1733c016bd1b165d63d91",
"category": "Unsecured",
"severity": "Major",
"status": "NEW",
"issues": [
{
"autoSuggestionId": null,
"issueId": "NiEQOTRlELcsXFbDSQjm",
"jobId": "8a8080966bda207d016bda614f5d2a48",
"status": "open",
"runId": null,
"jobName": "Dev",
"envName": "Master"
}
],
},
{
"id": "8a80800e6bd1733c016bd1b2cc844024",
"suggestionId": "tBAKv6Dh",
"projectId": "8a80800e6bd1733c016bd1b165d63d91",
"category": "Unsecured",
"severity": "Major",
"status": "NEW",
"issues": [
{
"autoSuggestionId": null,
"issueId": "NiEQOTRlELcsXFbDSQjm",
"jobId": "8a8080966bda207d016bda614f5d2a48",
"status": "open",
"runId": null,
"jobName": "Dev",
"envName": "Master"
}
],
}
]
For this see the below code:
Template Code
<button mat-raised-button class="float-right" (click)="nextVulnerability()">
Next<i class="material-icons">keyboard_arrow_right</i></button>
<button mat-raised-button class="float-right" (click)="previousVulnerability()">
<i class="material-icons">keyboard_arrow_left</i>Previous</button>
<table class="table">
<tbody>
<tr>
<th>Risk:</th>
<td>{{vulnerabilityDetails?.categoryName}}</td>
</tr>
<tr>
<th>API Endpoint:</th>
<td>{{vulnerabilityDetails?.method}}:{{vulnerabilityDetails?.endPoint}}</td>
</tr>
<tr>
<th>Auth:</th>
<td>{{vulnerabilityDetails?.auth}}</td>
</tr>
<tr>
<th>Severity:</th>
<td>
<span *ngIf="vulnerabilityDetails.severity == 'Critical'" class="text-danger"><i
class="fa fa-exclamation-circle"></i>
{{vulnerabilityDetails.severity}}</span>
<span *ngIf="vulnerabilityDetails.severity == 'Major'" class="text-danger"><i class="fa fa-warning"
aria-hidden="true"></i> {{vulnerabilityDetails.severity}}</span>
<span *ngIf="vulnerabilityDetails.severity == 'Minor'" class="text-warning"><i
class="fa fa-angle-double-down" aria-hidden="true"></i> {{vulnerabilityDetails.severity}}</span>
<span *ngIf="vulnerabilityDetails.severity == 'trivial'" class="text-warning"><i
class="fa fa-arrow-down"></i>
{{element.severity}}</span>
</td>
</tr>
<tr>
<th>Status:</th>
<td>
<span *ngIf="vulnerabilityDetails.status == 'NEW'" class="text-danger">Open</span>
<span *ngIf="vulnerabilityDetails.status == 'CLOSED' || vulnerabilityDetails.status == 'SKIPPED'"
class="text-success">Closed</span>
</td>
</tr>
<tr>
<th>Vulnerability Description:</th>
<td>{{vulnerabilityDetails?.issueDesc}}</td>
</tr>
<tr>
<th>Suggested Fix Time:</th>
<td>{{vulnerabilityDetails?.estimates}}</td>
</tr>
<tr>
<th>Discovered Date:</th>
<td>{{vulnerabilityDetails?.createdDate | timeAgo}}</td>
</tr>
<tr>
<th>Resource:</th>
<td>{{vulnerabilityDetails?.resourceName}}</td>
</tr>
<tr>
<th>Playbook:</th>
<td> <a href="javascript:;" [routerLink]="['/app/projects', id, 'template',playbookName]">
{{vulnerabilityDetails?.testSuiteName}}
</a>
</td>
</tr>
<tr>
<th>Scan:</th>
<td>
<a href="javascript:;" [routerLink]="[scanHistoryURL]">
Recent Scan
</a>
</td>
</tr>
<tr>
<th>Status Code:</th>
<td>{{vulnerabilityDetails?.respStatusCode}}</td>
</tr>
<tr>
<th>Suggestions:</th>
<td>{{vulnerabilityDetails?.suggestion}}</td>
</tr>
<tr>
<th>Bug Bounty Program Savings:</th>
<td>{{vulnerabilityDetails?.bounty | currency:0}}</td>
</tr>
<tr>
<th>False Positive:</th>
<td>{{vulnerabilityDetails?.falsePositive}}</td>
</tr>
<tr>
<th>Issue Id:</th>
<td>{{vulnerabilityDetails?.issues[0]?.issueId}}</td>
</tr>
</tbody>
</table>
The below is the code of ts for handling previous and next functionality
nextVulnerability() {
this.getDetailsByVulId("next")
}
previousVulnerability() {
this.getDetailsByVulId("prev")
}
getDetailsByVulId(action: string) {
if(this._clockSubscription != null)
{
this._clockSubscription.unsubscribe();
}
this.handler.activateLoader();
this.projectService.getVulDetailsPrevNext(this.id, this.vulnerabilityId, action).subscribe(vulRes => {
this.handler.hideLoader();
if (this.handler.handle(vulRes)) {
return;
}
this.vulnerabilityResult = vulRes['data'];
console.log("this.runNumResult = ", this.vulnerabilityResult);
this.router.navigate(['/app/projects', this.projectId, 'recommendations', this.id, 'details']);
}, error => {
this.handler.hideLoader();
this.handler.error(error);
});
}
The service written from where i am getting data.
getVulDetailsPrevNext(id,autoSuggestionId,action: string){
return this.http.get(this.serviceUrl + "/" + id + "/auto-suggestion/"+autoSuggestionId + action);
}
Can anyone suggest me what i have done wrong. I am not able to understand. When i click on previous and next buttons then it gives the below errors like "invalid id" from the back end.
When i use this code in my controller. I think ng-model can output value based on input right ?
ng-model = "$scope.title"
But when i implementation update data in my code. I'm confused because ng-model can output value but The value still output data.title even though I edited title input.
I edited this form in "tes1234" but the output still "tes"
Anybody to give me solution ? Thanks.
UPDATED
This my HTML code :
<div class="form-group">
<label class="control-label col-md-3">Title</label>
<div class="col-md-6">
<input type="text" name="title" class="form-control" ng-model="title">
</div>
</div>
$scope.result grab data from API and then I use ng-repeat
HttpService("POST", url, param, function(response){
$scope.parsing = angular.fromJson(response.data);
$scope.result = {};
angular.forEach($scope.parsing, function(item){
$scope.result[item._id] = item;
});
});
This is GetData() to grab data based on clicked and pass in my form
<tbody ng-repeat="data in result">
<tr>
<td>
{{$index + 1}}
</td>
<td>
{{ data._id }}
</td>
<td>
{{ data.title }}
</td>
<td>
{{ data.category.label }}
</td>
<td>
{{ data.user.name }}
</td>
<td width="20%">
<button type="button" class="btn btn-primary" ng-click="getData(data)"><i class="fa fa-edit"></i> Edit</button>
<button type="button" class="btn btn-danger"><i class="fa fa-trash"></i> Delete</button>
</td>
</tr>
</tbody>
This is GetData() to grab data based on clicked and pass in my form
$scope.getData = function(data) {
$scope.title = data.title;
}
And this is my save after data updated
$scope.Save = function() {
var data = $.param({
title : $scope.title,
});
console.log(data);
};
Data Object Based From API
{
"status": "200",
"data": [
{
"_id": "589c0484a6551f948e1d6914",
"parent_id": 0,
"parent_source": 0,
"category_id": "58942caba6551fd2c3347371",
"user_id": "58942d43a6551fd7123bdcb1",
"active": 1,
"status": 1,
"title": "coba tes",
"description": "coba tes",
"url": "coba-tes_6llapm",
"extra": "EXTRA",
"responded": "2017-02-09 12:56:20",
"level": 0,
"editor_pick": 0,
"up_vote": 0,
"down_vote": 0,
"revision": 0,
"answer_count": 2,
"updated_at": "2017-02-09 13:04:14",
"created_at": "2017-02-09 12:56:20",
"tags": [],
"user": {
"_id": "58942d43a6551fd7123bdcb1",
"status": 1,
"username": "asdasdad",
"email": "asdasdasd#gmail.com",
"image": "https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/16299070_1114043338706757_6701359761657365227_n.jpg?oh=7ed22de2d576dc9d3cfd6a89aa386153&oe=5942BC1F",
"about": "ini saya, saya suka makan dan belanja",
"ref_id": "https://www.facebook.com/app_scoped_user_id/1104332756344482/",
"name": "asdasd",
"login_ip": "192.168.100.4",
"notif_check": "2017-02-03 14:12:03",
"token": "$2y$10$EMGp1wWnnPUDRJ/dSybCIeei88jROcAqsAsgXri2l8j/H8FMSt5iS",
"updated_at": "2017-02-10 10:52:33",
"created_at": "2017-02-03 14:12:03"
},
"category": {
"_id": "58942caba6551fd2c3347371",
"label": "My Kids and I",
"active": 1,
"url": "my-kids-and-i",
"parent_id": 0,
"level": 0,
"dfp_interest": "[]",
"meta_title": "",
"meta_description": "",
"meta_keyword": "",
"updated_at": "2017-02-03 14:09:31",
"created_at": "2017-02-03 14:09:31"
}
}]
}
Just change var data = $.param... to $scope.data=$.param....
change the getDate Function like this
$scope.getData = function(data) {
$scope.title = data[0].title;
}
I have added demo.
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$scope.result = {
"status": "200",
"data": [{
"_id": "589c0484a6551f948e1d6914",
"parent_id": 0,
"title": "coba tes",
}]
}
$scope.getData = function(data) {
console.log(data);
$scope.title = data.title;
};
$scope.save = function() {
console.log($scope.title);
$scope.title;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp" ng-controller="customersCtrl">
<div class="form-group">
<label class="control-label col-md-3">Title</label>
<div class="col-md-6">
<input type="text" name="title" class="form-control" ng-model="title">
</div>
</div>
<table>
<tr ng-repeat="data in result.data">
<td>
{{$index + 1}}
</td>
<td>
{{ data._id }}
</td>
<td>
{{ data.title}}
</td>
<td>
{{ data.category.label }}
</td>
<td>
{{ data.user.name }}
</td>
<td width="20%">
<button type="button" class="btn btn-primary" ng-click="getData(data)"><i class="fa fa-edit"></i> Edit</button>
<button type="button" class="btn btn-danger"><i class="fa fa-trash"></i> Delete</button>
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" ng-click="save()"><i class="fa fa-edit"></i> Save</button>
</div>
first of all, thanks for the help. I am sure I'm doing something stupid somewhere but i cannot figure it out and it's driving me crazy. I tried to dollow many articles and suggestion on SO that was working for the other users but not for me.
I am building an app in jQuery, using handlebars as for templating, and getting the data from a backend api built in codeigniter.
I am using an IF statement within an #each to display the check in a checkbox if it was already checked.
The issue is that the IF statement doesn't seem to work within #each, since it display all the checkboxes as checked if they clearly aren't.
the jquery function is the following:
var load_checklist = function() {
var $checklistTable = $('#checklist-table');
var $row = $('#checklist-row').html();
$.get(BASE_URL + '/uapi/get_checklist', function(o) {
var template = Handlebars.compile($row);
$checklistTable.append(template(o));
}, 'json');
};
this is the html piece:
<tbody id="checklist-table">
<script id="checklist-row" type="text/x-handlebars-template">
{{#each checklist}}
<tr data-id="{{title}}">
<td>
<label class="fancy-checkbox">
<input type="checkbox" {{#if completed}}checked="checked"{{/if}}>
<span></span>
</label>
</td>
<td colspan="2">{{title}} completed {{completed}}</td>
<td style="text-align: right;">
<button class="btn-view-fund btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-list" aria-hidden="true"></span>
</button>
<button class="btn-view-fund btn btn-default btn-xs" type="button">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</td>
</tr>
{{/each}}
</script>
</tbody>
and the output from the api is the following:
{
"checklist": [{
"checklist_id": "1",
"user_id": "2",
"title": "test1",
"decription": "test",
"action": "test",
"action_target": "test",
"completed": "0",
"date_added": "2017-01-23 19:31:49",
"date_modified": "2017-01-23 19:31:49"
}, {
"checklist_id": "6",
"user_id": "2",
"title": "test2\r\n",
"decription": "test",
"action": "test",
"action_target": "test",
"completed": "1",
"date_added": "2017-01-23 19:31:49",
"date_modified": "2017-01-23 19:32:17"
}, {
"checklist_id": "11",
"user_id": "2",
"title": "test1",
"decription": "test",
"action": "test",
"action_target": "test",
"completed": "0",
"date_added": "2017-01-23 19:31:49",
"date_modified": "2017-01-23 19:31:49"
}]
}
I have alsot tried to do it through a helper adding but it doesn't work.
Handlebars.registerHelper('ifIsOne', function(value, options) {
if(value === 1) {
return options.fn(this);
}
return options.inverse(this);
});
this is the version I'm using
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.min.js"></script>
and jquery-2.1.1.min.js.
Thank you
my HTML code,
I want each user role is selected next to the select box of each user name,
inside the each loop of role i cant able to access the role of parent user node,
is it possible to compare the role id of user node with roles node roleid and when its equal, the option will be selected
<table>
<tr>
<p>peter is employee</p>
<p>john is admin</p>
<p>michel is manager</p>
</tr>
{{#user}}
<tr>
<td>
<input type="text" value="{{name}}">
</td>
<td>
<select>
{{#each ../roles}}
<option value="{{roleid}}">{{value}}</option>
{{/each}}
</select>
</td>
</tr>
{{/user}}
This is may Json
var data = {
"user": [
{ "name": "peter", "role": 1 },
{ "name": "john", "role": 2 },
{ "name": "michel", "role": 3 }
],
"roles": [
{ "roleid": 1, "value":"manager"},
{ "roleid": 2, "value":"employee"},
{ "roleid": 3, "value":"admin"}
]
};
fiddle url https://jsfiddle.net/Manu_S/egbwbfav/2/
thanks
You can access the parent node values and compare in your select box.
Please follow the Jsfiddle working that
https://jsfiddle.net/gsubbarao/nz0bc0pq/
<script id="t" type="text/x-handlebars">
<table>
<tr>
<p>peter is employee</p>
<p>john is admin</p>
<p>michel is manager</p>
</tr>
<tr>
<td> </td><td></td><td></td>
</tr>
{{#user}}
<tr>
<td>
<input type="text" value="{{name}}">
</td>
<td>
<select>
{{#each ../roles}}
<option value="{{roleid}}"
{{#ifCond ../role roleid}}
selected
{{/ifCond}}
>
{{value}}
</option>
{{/each}}
</select>
</td>
</tr>
{{/user}}
</script>
var data = {
"user": [
{ "name": "peter", "role": 2 },
{ "name": "john", "role": 3 },
{ "name": "michel", "role": 1 }
],
"roles": [
{ "roleid": 1, "value":"manager"},
{ "roleid": 2, "value":"employee"},
{ "roleid": 3, "value":"admin"}
]
};
Handlebars.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
var t = Handlebars.compile($('#t').html());
$('body').append(t(data));
So normal checkboxes in vuejs allows you to bind a model to it.
When this model has the values from checkboxes pre filled, those particular checkboxes appear checked.
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>
<input type="checkbox" v-model="selectedUsers" v-bind:value="{ id: user.id }">
</td>
<td>
<input type="checkbox" v-model="selectedUsers" value="{{ user.id }}">
</td>
</tr>
However you don't get the same behaviour when you bind the checkbox value to an object.
Following is the snippet:
new Vue({
el: '#app',
data: {
users: [{
"id": "1",
"name": "Shad Jast",
"email": "pfeffer.matt#yahoo.com"
}, {
"id": "2",
"name": "Duane Metz",
"email": "mohammad.ferry#yahoo.com"
}, {
"id": "3",
"name": "Myah Kris",
"email": "evolkman#hotmail.com"
}, {
"id": "4",
"name": "Dr. Kamron Wunsch",
"email": "lenora95#leannon.com"
}, {
"id": "5",
"name": "Brendon Rogahn",
"email": "verlie.buckridge#yahoo.com"
}],
selectedUsers: [{
"id": "1"
}, "1"]
}
})
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<h4>User</h4>
<div>
<table>
<tr>
<th>Name</th>
<th></th>
<th></th>
</tr>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>
<input type="checkbox" v-model="selectedUsers" v-bind:value="{ id: user.id }">
</td>
<td>
<input type="checkbox" v-model="selectedUsers" value="{{ user.id }}">
</td>
</tr>
</table>
</div>
<span>Selected Ids: {{ selectedUsers | json }}</span>
</div>
I have done it the following way, please suggest better ways, if any:
new Vue({
el: '#app',
data: {
users: [{
"id": "1",
"name": "Shad Jast",
"email": "pfeffer.matt#yahoo.com"
}, {
"id": "2",
"name": "Duane Metz",
"email": "mohammad.ferry#yahoo.com"
}, {
"id": "3",
"name": "Myah Kris",
"email": "evolkman#hotmail.com"
}, {
"id": "4",
"name": "Dr. Kamron Wunsch",
"email": "lenora95#leannon.com"
}, {
"id": "5",
"name": "Brendon Rogahn",
"email": "verlie.buckridge#yahoo.com"
}],
previousUsers: [{
"id": "2"
}, {
"id": "5"
}, "1", "5"],
updatedUsers: []
},
methods: {
check: function(user_id) {
var checked = false;
for (i = 0; i < this.previousUsers.length; i++) {
if (this.previousUsers[i].id == user_id) {
this.previousUsers.splice(i, 1)
return true
}
return false;
}
}
}
})
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<h4>User</h4>
<div>
<table>
<tr>
<th>Name</th>
<th></th>
<th></th>
</tr>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>
<input type="checkbox" v-model="updatedUsers" v-bind:value="{ id: user.id }" checked="{{check(user.id)}}">
</td>
<td>
<input type="checkbox" v-model="updatedUsers" value="{{ user.id }}">
</td>
</tr>
</table>
</div>
<span>Selected Ids: {{ updatedUsers | json }}</span>
</div>