AngularJS, checkboxes, and generating dynamic html - html

I am wanting to generate a table dynamically using Angular JS, based on what is checked on some checkboxes. The problem is that there are a few fields, we will call them relation/column, that I want to display ALWAYS, and the remaining fields only if their box is checked. The relation is searched for via a search box (relations can have multiple columns), and I want to display only the properties of that relation that are relevant to a user.
So
Update Time [X]
Update Status [ ]
Time Zone [ ]
Would display some html along the lines of
<table>
<tr>
<th> Relation </th>
<th> Column </th>
<th> Update Time </th>
</tr>
<tr ng-repeat= "result in results">
<td> {{result.relation}} </td>
<td> {{result.column}} </td>
<td> {{result.update_time}}</td>
</tr>
If no boxes were checked, only the relation and column fields would be populated. The documentation for Angular JS is taking me all over the place, so would anyone have an idea on how to do this?
edit : controller isn't working quite yet, I still need to filter the search results, but basically it goes
$scope.search = function(){
//validate form input
//create url with the input recieved
$http.get(url).success(function(data){
$scope.results = angular.fromJson(data);
});
}
I use mojolicious backend to grab the data I want. Again, the problem isn't that I can't get any data, or that I can't filter the results based on the relation. I want to be able to search based on relation, and only display the attributes of that relation that I want to, based on what is checked. THAT part, I can't figure out.
edit again : the firewall where I'm at prevents me from writing comments/upvoting. You shall be rewarded for your help when I get home tonight. Thank you thank you!

I think the best way to do this would be using ng-show expressions tied to a variable in the model.
For example.
<input type="checkbox" ng-model="updateTime">
makes a checkbox and ties the result to $scope.updateTime. You can then use this variable later on via the ng-show directive like so...
<th ng-show="updateTime"> Update Time </th>
...
<td ng-show="updateTime"> {{result.update_time}}</td>
this means that these elements will only show when updateTime is set to true (i.e the checkbox is checked.)
You can see an example here, I've only implemented the one field but it should be possible to extend it pretty easily!
http://plnkr.co/edit/W6Ht6dnGw4fBplI83fB1?p=preview

I would suggest using a custom filter with the checkbox scope variables passed in. Something like this:
html
<input type="checkbox" ng-model="checkbox1" />
<input type="checkbox" ng-model="checkbox2" />
<input type="checkbox" ng-model="checkbox3" />
... ng-repeat= "result in results|checkboxFilter:{checkbox1,checkbox2,checkbox3}"
filter.js
.filter('checkboxFilter', function() {
return function (results, checkbox1, checkbox2, checkbox3) {
var filtered_objects = angular.copy(results);
for (var i = 0, len = filtered_objects.length; i < len; i++) {
**modify your filtered_objects based on your checkboxes**
if (checkbox1) ...
if (checkbox2) ...
if (checkbox3) ...
}
return filtered_objects;
}
});
Maybe something like that.

Related

Manipulate Html table with Angular

very simple
what is the equivalent of this jQuery code
$('#message tr').eq(index).addClass('negative') in angular,
or how can i achieve the same result with angular
can't use [class.bind] the above job should be done in by clicking the button.
the button will pass some data to the function and based on some condition and checking the negative class will be added to the related row not to all of them.
You have not added any code, so I imagine you have something like:
<table>
<tr *ngFor="let data of arrayData;let i=index" [class.negative]="indexSelected==i">
<td>{{data?.prop1}}</td>
<td>{{data?.prop2}}</td>
<td><button
(click)="indexSelected=(indexSelected==i)?-1:i;
indexSelected!=-1 && diifer(data)">
select
</button>
</td>
</tr>
</table>
(or instead use a button add the "click" to the <tr>)
You can also pass the "index" to the function diifer like
(click)="diifer(data,i)"
And
diifer(data:any,index)
{
this.indexSelected=this.indexSelected==index?-1:index
if (this.indexSelected!=-1)
{
...do something..
}
}
NOTE: See that you check if indexSelected is the "row" you select. If true, you "unselect" making indexSelected=-1
NOTE2: remember that index goes from 0 to arrayData.length-1

html5 onclick update table data

I have a table that has js to allow me to sort the data. But I need to be able to change the data and have js still sort it when I click the header. I have a input box off to the side with a button. I am looking for a onclick way to change the table data from X to what is ever in that input box.
<td id="tabledata1">
1
</td>
I need to be able to change the "1" in that table data. I can not find the function code to effect that specific number. I am guessing it is something like this document.getElementById("tabledata1").style.color but instead of style.color there is something to reference table data.
It would look something like this
var cell = document.getElementById("tabledata1");
var button = document.getElementById("my-button");
var input = document.getElementById("my-input");
var par = document.getElementById("result");
button.addEventListener("click", function() {
cell.textContent = input.value;
});
<input id="my-input" type="text" />
<button id="my-button">Change Table Data</button>
<table>
<tr>
<td id="tabledata1">1</td>
</tr>
</table>
<p id="result"></p>
Breakdown
First query the document for the ids you want and store them into variables. You can then listen for the click event with the addEventListener function.
You can change the text of the table cell, by using the textContent property and setting it equal to the value of the input element.

How to make TableSorter.js working with the table on demad via some JS and inc.php file

I have a table that I want to make sortable. The problem is that this table has been loaded from the external file (inc.php) via some JS (filter-data.js) function. To be more precisely, I have a main.php page with the Submit button. When I click on it, that triggers some JS code which calls inc.php file to populate my table with its data on demand from MySQL base and then puts them both (table + data) back to the main page:
This is the table placeholder on the main page.
<div id="tableData"></div>
This is the submit button on the main page:
<input type="submit" onclick="genTable()" value="Populate users data">
This is what I am geting form the table.inc.php page:
<table id="my-table">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>45</td>
<td>34</td>
</tr>
<tr>
<td>23</td>
<td>17</td>
</tr>
</tbody>
</table>
I am not sure how and where to call TS function - should it be on the main.php page or table.inc.php page?
I tried almost everything but with no success.
$("#my-table").tablesorter();
If I skip JS and just require my table.inc.php file from main.php page, it works properly.
Thank you!
It is better practice to separate the HTML from scripting, so to do this, add this to your page (or even better, move the stuff inside the script tag into an external file):
<script>
// dom ready
$(function(){
// do something when the submit button is clicked
$('input[type=submit]').click(function(){
// generate table
genTable();
// add sorting
$("#my-table").tablesorter();
});
});
</script>
Then modify your submit button code by removing the onclick attribute:
<input type="submit" value="Populate users data">
If that doesn't work, could you share the genTable(); code with us?
Sadly, I'm about to go out of town for a week... hopefully I can help you before then.
What I would recommend doing is download my fork of tablesorter because it has an option to disable client-side sorting: serverSideSorting (reference).
Then you can bind to tablesorter's sortEnd function:
$("#my-table").on("sortEnd", function(e, table) {
// get sorting information
// [[0,0]] means sort the first column (zero-based index) in ascending direction
// [[0,1]] means sort the first column in a descending direction
// [[0,0], [2,0]] means sort the first and third columns, both in the ascending direction
var sortList = table.config.sortList,
// set the sort direction
// this is why I need to know what is stored in the #sort element,
// or how the server knows how to sort the data
d = 'something';
$('#sort').val( d );
genTable();
// initialize tablesorter again, because the entire table is being replaced
// Otherwise if you only update the tbody, use:
// $("#my-table").trigger('update');
$("#my-table").tablesorter({
theme : 'blue', // required theme option (tablesorter fork)
serverSideSorting : true
});
});

jQuery event bound to dynamically created DOM elements fires erronously

I have this markup.
<form action='xxx.php' method='post'>
<table>
<tr>
<th>Branch Id</th>
<td><input id="branchId" type="text" size="15%" name="branchId"></input></td>
<th>Branch Name</th>
<td colspan="3"><input id="branchName" type="text" size="75%" name="branchName"></input></td>
<td>
<div id="button">
<input type="button" id="btnAdd" value="Add" name="submit"/>
</div>
</td>
</table>
</form>
<!------- Something here--------------->
<table class="divTable" id="exisBranch">
<tr><th id="thBranchId">Branch Id</th>
<th id="thBranchName">Branch Name</th>
<th class="btn" id="tcEdit">Edit</th>
<th class="btn" id="tcDelete">Delete</th>
</tr>
</table>
What basically happens is I populate the second table records retrieved through AJAX. Each row has a 'branchId','branchName' and two buttons of class 'bt'. When I click the edit button, I need the corresponding 'branchId' and 'branchName' values inserted into input elements in the first table, so that I can edit them and later, when I click the "btnAdd", I can save them.
This is the jQuery I have.
function fun(){
var branchId=$(this).closest("tr").find("td").eq(0).html();
$("#btnAdd").click(function () {
if($("#btnAdd").val()=='Save')
{
alert(branchId);
//ajax call
}
});
}
$(document).ready(function(){
$("#exisBranch").on('click','.bt',fun);
$("input[type='button']").click(function(e){
e.preventDefault();
});
});
Everything works fine when I click the 'btnAdd' for the first time. The problem starts with the second and successive clicks on this button.Consider that there are 6 rows in the dynamically populated content, and that 'branchId' of each row is the corresponding row number.
When I first click on 'EDIT' button on the 2nd row, and then the 'btnAdd', an alert correctly pops up showing 2.
Problem is , if I then go on to click 'EDIT' on the 6th row, and then the 'btnAdd' , I get two alerts. The first one shows 2, then 6.I just want 6.
For the third round, it goes like 2,6, and what ever is clicked next. This is making my AJAX fire as many no. of times as the no. of clicks.
This is really infuriating.I just can't seem to figure out why. I am a jQuery novice, so please bear with me if this is something fundamental and I messed it up.Please let me know how to make it fire only once with the latest value, instead of it stacking up on my history of calls?
You shouldn't keep binding your Add button w/ each Edit click--move it out to your document ready.
<script>
var branchId; //keep track of which branch is under edit
function fun(){
branchId = $(this).closest("tr").find("td").eq(0).html();
var branchName = $(this).closest("tr").find("td").eq(1).html();
$('#branchId').val(branchId);
$('#branchName').val(branchName);
}
$(document).ready(function(){
$("#exisBranch").on('click','.btn',fun);
$("#btnAdd").click(function () {
if($("#btnAdd").val()=='Save') {
alert(branchId);
//ajax call
}
});
$("input[type='button']").click(function(e){
e.preventDefault();
});
});
<script>
*you have a number of typos in your stack post.
The problem is that you are attaching a new click handler each time that fun is called. These handlers are not unbound after they fire, so the handlers are building up. You could use jquery's one to ensure that each event fires only once.
Really though, your entire approach is not ideal. Off the top of my head, one possible improvement which wouldn't take too much re-engineering would be to store the IDs in an array, then when add is clicked, process the array and clear it. This would let you only have one handler on add as well as allow for batch ajax calls instead of one per id.

Information sent in an HTML form

I've a HTML file that shows to the user the contents of a database (it is shown as a table). The user can choose one of the rows.When this is done the selection made by the user is sent to a servlet that will work with that information.
Imagine that this servlet is going to look for files related to the information chosen by the user. What I'd like to do is to provide the user with the option of also choosing the number of files that are going to be looked for by the servlet. That way the user should be able to choose one of the rows shown in the table and should also be able of typing the numers of files that are to be looked for.
So far I'm able to send to the servlet what the user chooses in the table, but I'd like to know if it is possible to attach to this information the number of files requested.
This is my code:
<center><form action="administ" method=post >
<center><table>
<table border=\"1\"><tr><th></th><th>Titleo</th><th>Author</th><th>Album</th></tr>
<c:forEach items="${items}" var="item">
<tr>
<td><input type="radio" name="Song" value="${item.file}#${item.title}#${item.author}$${item.album}">
<td>${item.title}</td>
<td>${item.author}</td>
<td>${item.album}</td>
</tr>
</c:forEach>
</table></center>
<tr><td colspan=2><input type=submit value = play name = option></td></tr>
<tr><td colspan=2><input type=submit value = Delete name = option></td></tr>
At this point I want to add a new option that requires not only a new button, but also requires the user to introduce a number.
That depends. If you want single selection of rows using radiobuttons, then you could just put a single input field at bottom of table, next the submit button or so. E.g.:
<input type="text" name="numberOfFiles">
which you can obtain in the servlet as follows:
String numberOfFiles = request.getParameter("numberOfFiles");
But if you want multiple selection of rows using checkboxes or if you want this field to appear in each row at any way, then you need to give the radio/checkbox field a value of the row index. If you're using JSTL <c:forEach> to iterate over the rows (which I'd expect that you indeed do), then you can make use of the varStatus attribute to declare a LoopTagStatus. Inside the loop you can obtain the row index by LoopTagStatus#getIndex(). E.g.:
<table>
<c:forEach items="${items}" var="item" varStatus="loop">
<tr>
<td><input type="checkbox" name="selected" value="${loop.index}"></td>
<td><input type="text" name="number"></td>
</tr>
</c:forEach>
</table>
<input type="submit">
(to have single selection, just replace type="checkbox" by type="radio")
In the servlet, you can obtain all input fields with the same name in the order as they appear in the table as follows:
String[] numbersOfFiles = request.getParameterValues("numberOfFiles");
With checkbox-selection you can obtain the all selected row indexes and thus also the associated input field as follows:
String[] selectedIndexes = request.getParameterValues("selected");
for (String selectedIndex : selectedIndexes) {
int index = Integer.parseInt(selectedIndex);
String numberOfFiles = numbersOfFiles[index];
// ...
}
Or if it is a radiobutton-selected row which is single selection at any way:
String selectedIndex = request.getParameter("selected");
int index = Integer.parseInt(selectedIndex);
String numberOfFiles = numbersOfFiles[index];