Vue.js: Pass parameter to function in v-for - javascript

I have a table that loops through book objects and writes out values. I want to add buttons to edit and delete the objects. How do I pass parameters correctly to the methods?
So far I have tried this:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Title</th>
<th scope="col">Author</th>
<th scope="col">Genre</th>
<th scope="col">ISBN</th>
<th scope="col">UDC</th>
<th scope="col">Publisher</th>
<th scope="col">Year Published</th>
<th scope="col">Shelf Position</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr v-for="(book, i) in books" :key="i">
<th scope="row">{{ ++i }}</th>
<td>{{ book.title }}</td>
<td>{{ book.author }}</td>
<td>{{ book.genre }}</td>
<td>{{ book.isbn }}</td>
<td>{{ book.udc }}</td>
<td>{{ book.publisher }}</td>
<td>{{ book.year_published }}</td>
<td>{{ book.shelf_position }}</td>
<td><button type="submit" class="btn btn-secondary" v-on:submit="this.edit(book.book_id)">Edit</button></td>
<td><button type="submit" class="btn btn-secondary" onclick="this.delete('{{book.book_id}}')">Delete</button></td>
</tr>
</tbody>
</table>
I have tried two different ways both shown above, but it doesn't work. What am I doing wrong?

When referencing methods/data in templates in vue.js, you don't need to use this - you can refer to it directly by name. You should also be using v-on:click to listen for the events.
So you can change those buttons to:
<td><button type="submit" class="btn btn-secondary" v-on:click="edit(book.book_id)">Edit</button></td>
<td><button type="submit" class="btn btn-secondary" v-on:click="delete('{{book.book_id}}')">Delete</button></td>
This should work as long as edit and delete are defined in your component's methods.

Use the click listener without setting type to submit:
<td><button class="btn btn-secondary" #click="edit(book.book_id)">Edit</button></td>
<td><button class="btn btn-secondary" #click="delete(book.book_id)">Delete</button></td>
Reference: https://v2.vuejs.org/v2/guide/events.html

Related

HTML table rows with Vue(2) binding

I have a shopping cart / order list that I bound to an array which worked fine.
I recently added a row number for each item added to the array, and also a button row.
The problem is I bound them to a current row like so
<div id="table">
<table class="table table-sm table-bordered table-striped">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Product</th>
<th scope="col">Type</th>
<th scope="col">Attribute</th>
<th scope="col">Height</th>
<th scope="col">Width</th>
<th scope="col">Price</th>
<th width="1%" scope="col">Remove</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in table_products">
<td>{{ index +1 }}</td>
<td>{{ item.product }}</td>
<td>{{ item.type }}</td>
<td>{{ item.attribute }}</td>
<td>{{ item.height }}</td>
<td>{{ item.width }}</td>
<td>{{ item.price }}</td>
<td><button class="btn btn-danger" #click="deleteRow(index)">X</button></td>
</tr>
</tbody>
</table>
</div>
</div>
I never had a problem because the bound item values were null so the row was never created. But now Index and the button create the first row of the table.
Is there a way I can clear the array on page load, or am I going at this the wrong way?
edit : added my vue component for context
var table_products = new Vue ({
el : '#table',
data : {
table_products : [{
}]
},
I initialized table_products [{}] instead of []
It had an empty object in the array from initialization so it had an element.
Initializing an empty array instead fixed this issue as it did not have an element.
Thanks to Phil in the comments

django datepicker on datatable

I have to apply datepicker to my datatable to filter the data between two date range. I have applied my things and tried different codes but nothing worked out. My table contains date in the format( example- July 16,2019). I know it can be done by javascript but I am unable to do so. Please help.
<table id="table table-mutasi" data-toggle="table" data-pagination="true" data-search="true" data-show-columns="true" data-show-pagination-switch="true" data-show-refresh="true" data-key-events="true" data-show-toggle="true" data-resizable="true" data-cookie="true" data-cookie-id-table="saveId" data-show-export="true" data-click-to-select="true">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="id">center</th>
<th data-field="cabin" >cabin</th>
<th data-field="boooked_date">Booked date</th>
<th data-field="release_date">Release Date</th>
<th data-field="client">Client</th>
<th data-field="booked_by">Booked by</th>
{% if not request.user.is_superuser %}
<th>Actions</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ object.premises}}</td>
<td>{{ object.cabin }}</td>
<td>{{ object.booked_date }}</td>
<td>{{ object.release_date }}</td>
<td>{{ object.client }}</td>
<td>{{ object.booked_by }}</td>
{% if not request.user.is_superuser %}
<td>
<span class="glyphicon glyphicon-edit"></span>
<input type="hidden" id="cendel" value="{{object.id }}">
</span> </td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>

Passing variable to Json API and showing response with ng-repeat

I'm pretty new to AngularJS. I have two tables, one has a list of people that need interviews
// From vol.xslt
<section id="requested_interviews" class="row">
<h3>Unassigned Requests</h3>
<div class="table-responsive">
<table id="unassigned_table" class="table table-condensed">
<tr>
<th>Requested</th>
<th>First</th>
<th>Last</th>
<th>City</th>
<th>Region</th>
<th>Zip</th>
<th>Country</th>
<th>Action</th>
</tr>
<tr ng-repeat="p in prospects">
<td>{{ p.Requested }}</td>
<td>{{ p.First }}</td>
<td>{{ p.Last }}</td>
<td>{{ p.City }}</td>
<td>{{ p.Region }}</td>
<td>{{ p.Zip }}</td>
<td>{{ p.Country }}</td>
<td>
<button class="btn btn-small btn-default btn-block" ng-click="haversine( {{{{p.lat}}}}, {{{{p.lng}}}} )">Find Matches</button>
<button class="btn btn-small btn-default btn-block" ng-click="viewProspectDetais()">Prospect Details</button>
</td>
</tr>
</table>
</div>
When the user clicks the Find Matches button, the haversine function is called, which passes the latitude and longitude of the person into it, and the api responds with volunteers in that person's area:
// From controller
// Volunteer enpoint
$scope.haversine = function(lat, lng) {
$http.get(-- redact api url --).then(function(response) {
$scope.volunteers = response.data.row;
});
};
Now, when the function is triggered, it should update the view, and I think that's what I am having trouble with:
// From vol.xslt
<section id="potential_volunteers" class="row">
<h3>Potential Volunteers</h3>
<table class="table table-hover table-condensed">
<tr>
<th>First</th>
<th>Last</th>
<th>Street</th>
<th>Street 2</th>
<th>Street 3</th>
<th>City</th>
<th>Region</th>
<th>Zip</th>
<th>Country</th>
<th>Action</th>
</tr>
<tr ng-repeat="v in volunteers">
<td>{{ v.First }}</td>
<td>{{ v.Last }}</td>
<td>{{ v.Street_1 }}</td>
<td>{{ v.Street_2 }}</td>
<td>{{ v.Street_3 }}</td>
<td>{{ v.City }}</td>
<td>{{ v.Region }}</td>
<td>{{ v.Postal }}</td>
<td>{{ v.Country }}</td>
<td>
<button class="btn btn-small btn-default btn-block" ng-href="assignInterview()">Assign</button>
<button class="btn btn-small btn-default btn-block" ng-href="viewVolDetails()">Volunteer Details</button>
</td>
</tr>
</table>
I've verified that the endpoint works, and that my variables are showing up correctly within the button (XSLT requires my to use double braces for angular variables).
Thanks!
The answer was to change the start and end symbols for angular variables on the app itself. I guess that XSLT didn't like parsing the {{ and }} characters.
Changing my app declaration to
var app = angular.module('volApp',[]).config(function($interpolateProvider){
$interpolateProvider.startSymbol('[[').endSymbol(']]');
});
and all {{ to [[ and }} to ]] fixed the issue.

Need help fetching data JSON to scope AngularJS

i am newbie at AngularJS and in now trying to learn it. This time i am learning how to create one page app using codeigniter and angular with RESTful lib.
I have JSON like this :
[{"id":"25","title":"abc","description":"sss"},{"id":"26","title":"sd","description":"sdsd"}]
i just cannot fetch it to $scope with ng-repeat working no matter what i do. This is my function :
$http.get('Api/items').then(function(response)
{
$scope.items = response;
console.log(response);
});
and this is my table view :
<table class="table table-bordered pagin-table">
<thead>
<tr>
<th>No</th>
<th>Title</th>
<th>Description</th>
<th width="220px">Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in items">
<td>{{ $index + 1 }}</td>
<td>{{ x.title }}</td>
<td>{{ x.description }}</td>
<td>
<button data-toggle="modal" ng-click="edit(x.id)" data-target="#edit-data" class="btn btn-primary">Edit</button>
<button ng-click="remove(x,$index)" class="btn btn-danger">Delete</button>
</td>
</tr>
</tbody>
This is what happen when those all executed :
no array fetched by $scope at all. weird thing is the <tr> is repeated 5 time without any value. but when i call array[0] the $scope can fetch it :
<table class="table table-bordered pagin-table">
<thead>
<tr>
<th>No</th>
<th>Title</th>
<th>Description</th>
<th width="220px">Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in items">
<td>{{ $index + 1 }}</td>
<td>{{ x[0].title }}</td>
<td>{{ x[0].description }}</td>
<td>
<button data-toggle="modal" ng-click="edit(x.id)" data-target="#edit-data" class="btn btn-primary">Edit</button>
<button ng-click="remove(x,$index)" class="btn btn-danger">Delete</button>
</td>
</tr>
</tbody>
Where did i go wrong?? can someone help me??
It is because the promise returning raw HTTP response from the server rather than parsed result data. You should try this instead :
$http.get('Api/items').then(function(response)
{
$scope.items = response.data;
console.log(response);
});
#digit already pointed the issue in you $hhtp call. Now For this JSON:
[{"id":"25","title":"abc","description":"sss"},{"id":"26","title":"sd","description":"sdsd"}]
.
No need to give index number inside ng-repeat. //{{ x[0].title }}
<tr ng-repeat="x in items">
<td>{{ $index + 1 }}</td>
<td>{{ x.title }}</td>
<td>{{ x.description }}</td>
<td>
<button data-toggle="modal" ng-click="edit(x.id)" data-target="#edit-data" class="btn btn-primary">Edit</button>
<button ng-click="remove(x,$index)" class="btn btn-danger">Delete</button>
</td>
</tr>

AngularJS: passing array information along

I have a table that lists several objects in an array using ng-repeat and I was wondering, if there is an easy way to let the user select one of these objects by clicking on the row and viewing them in a separate <div>.
Here's the table:
<table class="table">
<tbody class="table-hover">
<tr>
<th scope="col">Name</th>
<th scope="col">Type</th>
<th scope="col">Approver</th>
</tr>
<tr ng-repeat="campaign in campaigns | filter: query" contenteditable="true">
<td>{{ campaign.name }}</td>
<td>{{ campaign.type }}</td>
<td>{{ campaign.approver }}</td>
</tr>
</tbody>
</table>
Let's say the user clicked on the first row. He would now see a <div> that contains all the information in this row for that object.
<div>
{{campaigns[].name}}
...
</div>
It could be achieved by several way. One of them as below.
<table class="table">
<tbody class="table-hover">
<tr>
<th scope="col">Name</th>
<th scope="col">Type</th>
<th scope="col">Approver</th>
</tr>
<tr ng-repeat-start="campaign in campaigns | filter: query" contenteditable="true" ng-click="campaign.showDetails = !campaign.showDetails">
<td>{{ campaign.name }}</td>
<td>{{ campaign.type }}</td>
<td>{{ campaign.approver }}</td>
</tr>
<tr ng-repeat-end ng-show="campaign.showDetails">
Your can dispalay here rest of the information from campaign object.
</tr>
</tbody>
You could seed the example http://codepen.io/anon/pen/beNbwp
Ok, so if I understand your problem, the solution could be to use ng-click :
(considering campaign.name unique for each campaigns)
<tr ng-repeat="campaign in campaigns | filter: query" contenteditable="true" ng-click="doSmth(campaign.name)">
<td>{{ campaign.name }}</td>
<td>{{ campaign.type }}</td>
<td>{{ campaign.approver }}</td>
</tr>
Then in your controller :
$scope.doSmth = function(campName) {
$state.go(campName); //example
};
Another solution, using ui-sref :
Considering you define a url: '/folder/campaignPage?name' in your $stateProvider.
<tr ng-repeat="campaign in campaigns | filter: query" contenteditable="true" ui-sref="campaignPage({ name: campaign.name })">
<td>{{ campaign.name }}</td>
<td>{{ campaign.type }}</td>
<td>{{ campaign.approver }}</td>
</tr>
Another way u can do it easily if u also create a button in ng-repeat like
<td><input type="button" value="select" class="btn btn-info btn-sm" ng-click="populate(campaign )" /></td>
And then
$scope.populate = function (campaign) {
$scope.Name = campaign.Name;
}
It's simple to use.

Categories