tags:

views:

95

answers:

3
$selectMenus = $("#experiences").find('select');

$tab.find('input').each(function(i) {
    var $elem = $(this);
    var value = $elem.attr('value');
    if(!value)
     value = ' ';
    $parent = $elem.parent();
    $elem.remove();
    $parent.html(value);
});

$tab.find('select').each(function(i) {
    $('option', this)[$selectMenus[i].selectedIndex].selected = true;
    var $elem = $(this);
    var value = $elem.attr('value');
    if(!value)
     value = ' ';
    $parent = $elem.parent();
    $elem.remove();
    $parent.html(value);
});

Note the two are almost the same.

+1  A: 

Try this:

var i = 0;
$tab.find('input, select').each(function() {
    var $elem = $(this);

    if (this.tagName == 'select')
        $elem.val($selectMenus[i++].selectedIndex)

    var value = $elem.val();

    $elem.parent().html(value ? value : ' ');
});
Greg
find('input, select') is what I like,but pay attention to the variable i,it's where the difficulty locates.
Shore
Edited to fix..
Greg
+1  A: 

Well I could see this optimzation:

function doSomething(elem)
{
    var value = $(elem).attr('value') ? $(elem).attr('value') : ' ';
    $(elem).parent().html(value);
}

$tab.find('input').each(function(i) {
    doSomething(this);
});

$tab.find('select').each(function(i) {
    $('option', this)[$selectMenus[i].selectedIndex].selected = true;
    doSomething(this);
});

I think if you already replace the parents HTML you don't have to remove element anymore because it already got replaced (anybody correct me if I'm wrong). The way of compacting it is just a way of personal preference though. Always keep readability in mind, too. Too many optimzations like this might make it really hard to dig into. I think for the sake of size a JavaScript packer for the production code might be a good choice as well.

Daff
Can you optimize it by:find('input, select')?The main difficulty is caused by the variable i.
Shore
True... it doesn't even look very nice. I agree that tvanfosson solution is the nicest one :)
Daff
+4  A: 

This depends on the fact that input elements don't contain option elements, but I think it's what you are looking for. In the case where there are no option elements, the attribute is simply not applied. Note that if you are replacing the HTML of the parent element there is no need to explicitly remove it's child elements from the DOM.

var elems = $tab.find('input, select');
elems.each(function() {
    var $elem = $(this);
    var i = elems.filter('select').index($elem);
    $(elem).find('option')
           .eq( $selectMenus[i].selectedIndex )
           .attr('selected','selected');

    var value = $elem.val();
    if(!value) value = ' ';
    $elem.parent().html(value);
});
tvanfosson
You didnt pay attention to the variable i .It's almost there,though.
Shore
Fixed. Requires traversing the list again to find the specified index.
tvanfosson
Almost right,except that should make sure i>=0 before running:$(elem).find('option') .eq( $selectMenus[i].selectedIndex ) .attr('selected','selected');
Shore
Otherwise will be terminated unexpectedly.
Shore