开发者

Creating <td> elements with customer behavior on the fly in jQuery

Just getting started with jQuery, and I've had some success so far. I've created a handler that updates a <table> every time a user makes a selection from a dropdown. It looks mostly like this:

function loadAttributes() {
$.ajax({
    type: "POST",
    url: "../ws/itemSearch/getAttributesForItemType",
    contentType: 'application/xml',
    data: '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.itemsearch.foo.com/">'
          + '<soapenv:Header/><soapenv:Body><ser:getAttributesForItemType>'
          + '<arg0>' + this.value + '</arg0>'
          + '</ser:getAttributesForItemType></soapenv:Body></soapenv:Envelope>',
    processData: false,
    dataType: "xml",
    success: function(data) {
        var attributes = '<table summary="Attribute Section"><tr class="underline">';

        var attCount = 0;

        $(data).find("return").each(
            function() {
                if (++attCount % 4 == 0) {
                    attributes += '</tr><tr class="underline">';
                }

                // TODO PMA click handler to the new <td> element
                attributes += '<td>' + this.textContent + '</td>';
            }
        );

        attributes += '</tr></table>';

        $("div[id=attributes]").html(attributes);
    }
});
}

As you can see my next step is to not just add literal <td> elements to the row containing the attributes, but to add a click handler to them. This click handler would append the contents of the <td> to a text box; something like:

tdItem.click(fun开发者_JAVA百科ction() {
    $("input[name=search]").append(tdItem.textContent);
}

To do that, I'd prefer to create each td item as a separate Element and build up the table in an object-oriented manner using <tr> elements rather than pasting together a literal string which is what I'm doing now. Most of the examples on the jQuery site have to do with adding listeners to existing elements and not to building up a new section of the document like this on the fly every time. At the very least, can someone point me to a good tutorial on how to accomplish what I'm trying to do here?


This is actually fairly simple to achieve and I would recommend taking advantage of some jQuery functions when writing your html building.

First $("<tr></tr") will create a tr element stored in a jQuery object as if you had just selected it. If you are building html as above I would recommend changing to something like this in your success function.

    var attributes = $('<table summary="Attribute Section"></table>');

    var attCount = 0;
    var attributeRow = $('<tr class="underline"></tr>');

    $(data).find("return").each(
        function() {
            if (++attCount % 4 == 0 && attCount != 0) {
                attributes.append(attributeRow.clone());
                attributeRow = $('<tr class="underline"></tr>');
            }

            // TODO PMA click handler to the new <td> element
            var attribute =  $('<td>' + this.textContent + '</td>'); 
            attribute.click(function(){//click function});              
            attributeRow.append(attribute );

        }
    );
    //add the last attribute row
    attributes.append(attributeRow);
    $("div[id=attributes]").append(attributes);

Above you will notice that You now have the attribute td generated as a jQuery object that you can apply click functions to.


The only way to do that with string literals is to add an onclick attribute to your td elements like

 attributes += '<td onclick="somefunction();">' + this.textContent + '</td>'; 

that would work, but I would not recommend that. To stay unobtrusive, use jQuery objects for table creation. For instance

  success: function(data) {  
    var $table = $('<table summary="Attribute Section"></table>');

    $table.append($('<tr class="underline"></tr>'));

    var attCount = 0;  

    $(data).find("return").each(  
        function() {  
            if (++attCount % 4 == 0) {  
                $table.append($('<tr class="underline"></tr>').append($('<td/>', {
                    click:   function(e){
                         alert($(this).text());
                    }
                }))); 
            }  
        }  
    );  

    $("div[id=attributes]").empty().append($table);  
} 


To me, a more elegant approach to your click handling for the td's is to put one click handler on the table itself, and let it catch the click events that bubble up from the td's. That way you don't need to worry about adding handlers to each td in the table. It's also better for performance, though in this situation, I doubt it matters much in that regard.

Here's what you would do (you could add this right after you declare the $table variable):

$table.click(function(e) {
   var target = $(e.target);

   if (target.is('td')) {

      var input = $('input[name=search]');
      input.val( input.val() + target.text() );

      e.stopPropagation();
   }
});
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜