开发者

jQuery n times .append($('<td></td>')) = less than n columns?

var user = {};
var row = $('<tr></tr>')
   .append($('<td></td>').text(user ? user.call_id : ''))
   .append($('<td></td>').text(user ? user.phone_number : ''))
   .append($('<td></td>').text(开发者_开发技巧user ? user.dialed_number : ''))
   .append($('<td></td>').html(user && user.admin ? '<span class="textgreen">admin</span>' : 'guest'))
   .append($('<td></td>').append(_talking(user ? user.mute : 0)))
   .append($('<td></td>').append($('<span></span>').addClass('timer').text(user ? user.duration : '')))
   .append($('<td></td>').addClass('nowrap').append(_userButtons(user)))
;
alert( row.find('td').size() );    // = does NOT always alert 7, but a smaller value

Why is that so?

At the moment, user.dialed_number is undefined, therefore the missing column is the third one. And it doesn't matter how much I repeat that column, the result is always 6 in my project.

** UPDATE **

Here is a simplified jsfiddle showing the problem; it should output 7, but it shows 4


AHA!

$('<td></td>').text(undefined)

is the same as

$('<td></td>').text()

Which as per the jquery document for .text (look at the top right of the doc) it returns the text inside the element. Then you append that text (which is an empty string) to the <tr>. And that is why the <td> is not appended

Simple fix:

$('<td></td>').text((true ? undefined : 'false') || '') // oops should  be ||

will do an empty string when the first part can be coerced to null (like undefined, 0, null, '', and 0.0)

Proof of concept: JS Fiddle


If any one of the expressions passed to .text() evaluates to null or undefined, the call to .text() will return the text of the TD - which is nothing - instead of the jQuery collection representing the TD. So you'd append 6 TDs and a nothing.


You're checking that the user exists each time, but not checking if the property exists which is returning undefined and making your statement append the contents of the td (which is nothing) instead of the td itself.

If you change your tests to check for the property instead, it works: Demo


In your jsfiddle, the reason it is only showing 4 is that the properties on user are not defined.

Look at this jsfiddle

Maybe your user properties are not defined?


I would strongly suggest you stop trying to be quite so clever and single-step each append and see what's happening, rather than trying to do it all in one line. For one thing, it probably isn't doing what you think it should be doing anyway the way you wrote it - each td is getting inserted INSIDE the previous one!

Try this way:

var row = $('<tr></tr>');
row.append($('<td></td>').text(user ? user.call_id : ''));
row.append($('<td></td>').text(user ? user.phone_number : ''));
row.append($('<td></td>').text(user ? user.dialed_number : ''));
row.append($('<td></td>').html(user && user.admin ? '<span class="textgreen">admin</span>' : 'guest'));
row.append($('<td></td>').append(_talking(user ? user.mute : 0)));
row.append($('<td></td>').append($('<span></span>').addClass('timer').text(user ? user.duration : '')));
row.append($('<td></td>').addClass('nowrap').append(_userButtons(user)));

alert( row.find('td').size() );    // = alerts 6 when it should be 7

Also, when I run your code even with your crazy syntax (after ensuring that all functions and variables are defined and exist) I get 7.


The script appends the cell to the previous cell, not the row. $.end() returns the selected object at the beginning of the chain, i.e.:

    $('tr', this).append($('<td>').text(user ? user.call_id : ''))
                 .end().append($('<td>').text(user ? user.phone_number : ''))
                 .end().append($('<td>').text(user ? user.dialed_number : '')) //etc.


corrected version

function _talking() {
    return $('<span>TalkingFn</span>');   
}
function _userButtons() {
    return $('<button>button1</button><button>button2</button>');   
}

var user = {};

var row = $('<tr></tr>')
    .append($('<td></td>').text(user.call_id ? user.call_id : '{calli_id}'))
    .append($('<td></td>').text(user.phone_number ? user.phone_number : '{phone_number}'))
    .append($('<td></td>').text(user.dialed_number ? user.dialed_number : '{dialed_number}'))
   .append($('<td></td>').html(user && user.admin ? '<span class="textgreen">admin</span>' : 'guest'))
   .append($('<td></td>').append(_talking(user.mute ? user.mute : 0)))
   .append($('<td></td>').append($('<span></span>').addClass('timer').text(user.duration ? user.duration : '')))
   .append($('<td></td>').addClass('nowrap').append(_userButtons(user)))
;
alert( row.find('td').size() );    // = alerts 6 when it should be 7

$('#foo > tbody').append(row);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜