How do i find index of my object? - javascript

I have a table that is dynamicaly created something like this:
userData = Object Object Object...etc;
Object= username : ....
level:
regdate:
JavaScript code:
var buildTable = function () {
for (var i = 0, l = userData.length; i < l; i++) {
buildRow(userData[i]);
}
var buildRow = function (data) {
var html = '<tr><td>' + data.username + '</td>' +
'<td>' + data.level + '</td>' +
'<td>' + data.regstatus + '</td>' +
'<td>' + data.regdate + '</td>' +
'<td>' +
'<button value = "edit" id = "edit" onclick="tableOfUsers.editUser()">Edit</button>' +
'<button value= "delete" id = "delete" onclick="tableOfUsers.deleteUser()">Delete</button>' + '</td>';
$('#tableBody').append(html);
};
I have edtiUser/deleteUser function and i want when i click on edit/delete to edit/delete my row , my question is how do i find index of my object that i want to edite/delete without haveing an id field just with index of my objects?

Modify your code like this
for (var i = 0, l = userData.length; i < l; i++) {
buildRow(userData[i], i);
}
and
var buildRow = function (data, index) {
and
'<button value = "edit" id = "edit" onclick="tableOfUsers.editUser('+index+')">Edit</button>' +
'<button value= "delete" id = "delete" onclick="tableOfUsers.deleteUser('+index+')">Delete</button>' + '</td>';
$('#tableBody').append(html);
notice that we are passing index to the method being called from inside html strings.

Related

Coffeescript : For loop to concatenate HTML <td> element

Playing around a coffeescript. I have the following for loop to concat a html element in native javascript which works well. At the moment I just couldnt get the value json data i.e i.a , i.b from coffeescript.
//.js file
function createTr(json){
var tr='';
for (var i=0;i<json.data.length;i++){
var data ='<tr><td>' + json.data[i].a + ' - ' + json.data[i].b +
'</td>'+
'<td>' + json.data[i].c +
'</td>'+
'<td>' + json.data[i].d +
'</td>'+
'</tr>';
tr +=data;
}
return tr;
}
The coffescript is per below
//.coffeescript
createTr = (json) ->
tr=''
tr + '<tr><td>' + i.a + '-' + i.b+'</td> <td>'+i.c+'</td><td>'+i.d+'</td></tr>' for i in json.data
tr
the source map for the autogenerated javascript from the coffeescript as per below
//autogenerated js file from coffeescript file above
createTr = function(json) {
var i, j, len, ref, tr;
tr = '';
ref = json.data;
for (j = 0, len = ref.length; j < len; j++) {
i = ref[j];
tr + '<tr><td>' + i.a + '-' + i.b + '</td><td>' + i.c + '</td><td>' + i.d + '</td></tr>';
}
return tr;
};
The only difference is a missing assignment. The CoffeeScript version should be:
createTr = (json) ->
tr=''
tr += '<tr><td>' + i.a + '-' + i.b+'</td> <td>'+i.c+'</td><td>'+i.d+'</td></tr>' for i in json.data
tr
##.coffee file
createTr = (json) ->
tr = ''
for item in json.data
data = """<tr>
<td>#{item.a}-#{item.b}</td>
<td>#{item.c}</td>
<td>#{item.d}</td></tr> """
tr += data
return tr
And read http://coffeescript.org/ about loop, string and variables in string like "Some text #{variable}"
I prefer to use a join on the array that the for loop creates:
createTr = (json) ->
('<tr><td>' + i.a + '-' + i.b+'</td> <td>'+i.c+'</td><td>'+i.d+'</td></tr>' for i in json.data).join("")
or kind of like #yavor.makc if it was my code I might focus on readability:
createTr = (json) ->
(for i in json.data
"
<tr>
<td>#{i.a}-#{i.b}</td>
<td>#{i.c}</td>
<td>#{i.d}</td>
</tr>
"
).join("")

How to optimize the DOM inserting loop

For example : I want to insert many tr in a table like this
var tbody = $('#tbody')
// Suppose the articlelist is the data from ajax
while (articlelist.length > 0) {
var article = articlelist.shift(),
var tr = $(' <tr>'
+' <td>'+article.id+'</td>'
+'<td>' + article.channelid +'</td>'
+ '<td>'+article.comment+'</td>'
+'<td>'+article.last_edit_time+'</td><td>'
)
tbody.append(tr)
}
To avoid create the <tr>...</tr> in loop .Is it possible to use a class to generate the tr content ?
An optimized version:
var tbody = $('#tbody'),
htmlStr = "";
for (var i = 0, len = articlelist.length; i < len; i++) { // avoid accessing 'length' property on each iteration
htmlStr += '<tr><td>' + articlelist[i].id + '</td>'
+ '<td>' + articlelist[i].channelid + '</td>'
+ '<td>' + articlelist[i].comment + '</td>'
+ '<td>' + articlelist[i].last_edit_time + '</td><td><tr>';
}
tbody.append(htmlStr); // parses the specified text as HTML or XML and inserts the resulting nodes
You could use a loop to concatenate all the strings, then append this lengthy string all at once. This would help with performance for many trs
var tbody = $('#tbody')
var rows = ''
while (articlelist.length > 0) {
var article = articlelist.shift(),
rows += '<tr><td>'+article.id+'</td>'
+'<td>' + article.channelid +'</td>'
+ '<td>'+article.comment+'</td>'
+'<td>'+article.last_edit_time+'</td><tr>';
}
tbody.append(rows)
add a function like this to do this for you.
while (articlelist.length > 0) {
make_content(article);
}
function make_content(article) {
var tbody = $('#tbody');
var tr = $(' <tr>'
+' <td>'+article.id+'</td>'
+'<td>' + article.channelid +'</td>'
+ '<td>'+article.comment+'</td>'
+'<td>'+article.last_edit_time+'</td><td>'
)
tbody.append(tr)
}

How can I make pagination for my dynamic table?

My table is created with dynamic OO javascript and now I have to make pagination for rows - something like 5 rows(users) on the page :-? Also I need to display the pagination numbers when there are more than 5 users ...
This is the pice of code that make the display of the table :
(function (window) {
function ListView(store) {
var me = this;
this.store = store;
this.defaultTemplate = '<tr data-id = "{{id}}">' +
'<td><button class = "edit btna" type="button"></button>' +
'<button class = "delete btna" type="button" ></button></td>' +
'<td class = "userCol">' + '{{username}}' + '</td>' +
'<td class = "levelCol">' + '{{level}}' + '</td>' +
'<td class = "regCol">' + "<img src='img/" + '{{regstatus}}' + "_registered.png'>" + '</td>' +
'<td class = "dateCol">' + '{{regdate}}' + '</td>' +
'</tr>';
$(this.store).on("storeLoad", function () {
var data = this.getUsers();
me.show(data);
});
}
ListView.prototype.show = function (data) {
var i, l;
var view = '';
for (i = 0, l = data.length; i < l; i++) {
var template = this.defaultTemplate;
template = template.replace('{{id}}', data[i].id);
template = template.replace('{{username}}', data[i].username);
template = template.replace('{{level}}', data[i].level);
template = template.replace('{{regstatus}}', data[i].regstatus);
template = template.replace('{{regdate}}', data[i].regdate);
view = view + template;
}
console.log(data);
$('#userList').html(view);
};
// Export to window
window.app.ListView = ListView;
})(window);
Any ideeas ?

How can i update data in html after modify the object?

I have this function that modify my existing object by ID :
var updateUser = function () {
var id = $("#userId").val();
var user = findObjectById(id);
user.username = $('#username').val();
user.level = $('#level').val();
user.regstatus = $('#regstatus').val();
user.regdate = $('#regdate').val();
$(".table").show();
$("#newUser").show();
$("#userForm").hide();
$("#updateUser").hide();
};
How can i replace my curent data from HTML with modified data ?
This is my function for creating rows :
var buildRow = function (data) {
var html = '<tr id = ' + data.id + '>' +
'<td>' + data.username + '</td>' +
'<td>' + data.level + '</td>' +
'<td>' + data.regstatus + '</td>' +
'<td>' + data.regdate + '</td>' +
'<td>' +
'<button class="btn btn-info"value="Edit" onclick="userList.editUser(' + data.id + ')">Edit</button>' + ' ' +
'<button class="btn btn-danger" value="Delete" onclick="userList.deleteRow(' + data.id + ')">Delete</button>' + '</td>' +
'</tr>';
$("#users").append(html);
};
P.S i want to update in the same place and my id should be the same.
I modified your prototype jsFiddle a bit, so it contains a working example.
I needed to modify some parts to get it work, for example updating the object I added a function.
updateObjectById = function (id, obj){
for (var i = 0, l = userData.length; i < l; i++) {
if (userData[i].id == id) {
userData[i] = obj;
}
}
};
You should be able to work it out I guess, by the given jsFiddle
As I understand it you want to update the table when running "updateUser". There are basically three ways to update the data in your case.
Rebuild the whole row
Pick out specific cells in the table and change the content
Use a two way databinding framework
In my experience the best solution, and how f.ex. Backbone does it, is just recreating all the HTML when your data changes. two way databinding is even more powerful, but seems overkill in this situation.
So basically in your updateUser function:
var row = buildRow(user);
var $existingRow = $(id);
if ($existingRow.length) {
$existingRow.replaceWith(row);
} else {
$('#users').append(row);
}
Now, this of course requires a change to your "buildRow" function, not making it append the row, but return it.
Hope this gets you further...

get drop down box attributes

In the below i have a a div with employee names and ahave to assign a grade for them,my question is that i have get the empid for all the selected values in getgrade_values function.Using jquery how to get the ids of the drop down box with its value where the values are selected when on click of evaluate function
function getgrade_values(empid)
{
var ele='<select id="'+ empid +'" name="emp" style="width:40px;margin:0px 0pt;" >';
ele += '<option value=""></option>';
ele += '<option value="A">A</option>';
ele += '<option value="B">B</option>';
ele += '<option value="C">C</option>';
ele += '<option value="D">D</option>';
ele += '<option value="E">E</option>';
ele += '<option value="F">F</option>';
ele += '</select>';
return ele;
}
function sendparams(data)
{
if(data.status == 1)
{
var ele='<tr id="std"><td><b>Evaluate:</b></label> </td></tr>';
for(var l=0;l<data.emparr.length;l++)
{
ele += '<tr><td><div id="'+ data.emparr[l].id +'">' + data.emparr[l].name + "</td><td>" + getgrade_values(data.emparr[l].id) + '</div></td></tr>';
ele+= '<input type="button" value="Evaluate" onclick="evaluate();"';
}
}
var select = $('select[name="emp"]')
var empId = select.attr('id')
alert('empId = '+empId)
select.children('option:selected').each(function() {
alert('grade selected = ' + $(this).val())
})
DEMO : http://jsfiddle.net/hdTEP/
Currently, you will have 2 elements with id="<employeeId>". As ids should be unique across an entire page, you should consider appending the type of element you are representing, for example id="<employeeId>_gradeInput" for your grade dropdown. Next, for each user it seems like you have a button to submit a grade. I would call evaluate with the employee id associated with that button.
function getgrade_values(empid){
var ele='<select id="'+ empid +'_gradeInput" name="emp" style="width:40px;margin:0px 0pt;" >';
..//Remaining code
}
function sendparams(data) {
if (data.status == 1) {
var ele =
'<tr id="std">' +
'<td>' +
'<b>Evaluate:</b>' +
'</td>' +
'</tr>';
for (var l = 0; l < data.emparr.length; l++) {
var employeeId = data.emparr[l].id;
ele +=
'<tr>' +
'<td>' +
'<div id="' + employeeId + '_divContainer">' +
data.emparr[l].name +
'</div>'
'</td>' +
'<td>' +
getgrade_values(employeeId)
'</td>' +
'</tr>';
ele += '<input type="button" value="Evaluate"
onclick="evaluate(' + employeeId + ');"';
}
}
function evaluate(employeeId){
var gradeValue = $('#' + employeeId + '_gradeInput').val();
..//Your other evaluate code here
}

Categories