Detect span sibling of input type search

That is way passed my pay scale but its really good to see and thank you again, learning loads from this, and am documenting…

This does work really well but it ignores the one search field that isn’t dynamically created. This one sits above the dynamically created table, but that bit of code is very different to the others isn’t it.

Although I do ask for help, I do try and work it out myself too, so thank you again

Ok I got it working, by changing the line below

from

addBack('input[type="search"]')

to

add('input[type="search"]')

I’m going to ask a question to try and anticipate a question I know will come.

Below is not specific for type=search, its just on input.

Is there a way to say for example all input except type=hidden, or any other type that needs to be disregarded.

// Listen to keyboard events on the search fields
$(document).on('keyup', 'input', function () {
    var $next = $(this).next()

    // Create a clear button if it does not exist
    var $clearBtn = $next.is('.clearBtn')
        ? $next
        : $('<span class="clearBtn">&times;</span>').insertAfter(this)

    // Toggle that button depending on the input value
    $clearBtn.toggle(this.value !== '')
})

// create clear buttons
$(document).on('click', '.clearBtn', function () {
    // Trigger a "change" event on the input after having cleared it
    $(this).hide().prev('input').val('').trigger('change')
})

// check if any search fields have text to allow clear to appear ( found on google :) )
var observer = new MutationObserver(function (records) {
    records.forEach(function (record) {
        if (record.type === 'childList') {
            // Find all search fields among the added nodes, and
            // dispatch a "keyup" event to trigger the check
            $(record.addedNodes)
                .find('input')
                .add('input')
                .trigger('keyup')
        }
    })
})

// Observe the complete body for changes to the child
// list, i.e. nodes that were added, moved or removed
observer.observe(document.body, {
    childList: true,
    subtree: true
})

Tried doing it this way, not right though by the looks

$(document).on('keyup', ('input[type="search"]', 'input[type = "text"]', 'input[type = "email"]'), function () {

Well the purpose of the .addBack() call is to capture single input elements as well – otherwise you’ll only get input elements that are descendants of the addedNodes, not addedNodes that are themselves search fields. It is an edge case, but certainly one to take into account.

Using .add() will work too, but that triggers a “keyup” event on all the search fields on the page whenever any arbitrary element gets added to the DOM… which is probably not what you want.

You might however trigger a “keyup” event on all fields right away on page load to initialize hard-coded fields in the markup:

$('input[type="search"]').trigger('keyup')

Edit: But now that you’re going the mutation observer route, there’s really no need to wait for “keyup” events any more to initialize the clear buttons. We’re always immediately triggering that event anyway, so we might just as well initialize the clear button directly:

// Toggle the clear button
$(document).on('keyup', 'input[type="search"]', function () {
  $(this).next('.clearBtn').toggle(this.value !== '')
})

// Clear the search field
$(document).on('click', '.clearBtn', function () {
  $(this).hide().prev('input[type="search"]').val('').trigger('change')
})

// Add a clear button to an input field 
var addClearBtn = function () {
  $('<span class="clearBtn">&times;</span>')
    .toggle(this.value !== '')
    .insertAfter(this)
}

// Initialize all search fields present on the page...
$('input[type="search"]').each(addClearBtn)

// ... and any search fields that get added later on
var observer = new MutationObserver(function (records) {
  records.forEach(function (record) {
    if (record.type === 'childList') {
      $(record.addedNodes)
        .find('input[type="search"]')
        .addBack('input[type="search"]')
        .each(addClearBtn)
    }
  })  
})

observer.observe(document.body, {
  childList: true,
  subtree: true
})

Sure, you can use regular CSS selectors here:

$(document).on('keyup', 'input:not([type="hidden"])', function () {/* ... */})

I see with addBack, I put it back as per your code above and all is good apart from the clear not loading when the page is refreshed, so I thought i’ll try it again just out of curiosity with just add, and the page crashes.

I think I’m right in that in the edit, you advised that adding the line below wasnt needed, as adding that doesnt fix the clear cross not appearing issue when there text in the one input field.

//$('input:not([type="hidden"])').trigger('keyup');

Also ye good idea with using input:not for the hidden fields.

It’s exactly like yours, but below is where I am with it.

// Toggle the clear button
$(document).on('keyup', 'input:not([type="hidden"])', function () {
    $(this).next('.clearBtn').toggle(this.value !== '');
});

// Clear the search field
$(document).on('click', '.clearBtn', function () {
    $(this).hide().prev('input:not([type="hidden"])').val('').trigger('change');
});

// Add a clear button to an input field 
var addClearBtn = function () {
    $('<span class="clearBtn">&times;</span>')
        .toggle(this.value !== '')
        .insertAfter(this);
};

// Initialize all search fields present on the page...
$('input:not([type="hidden"])').each(addClearBtn);

// ... and any search fields that get added later on
var observer = new MutationObserver(function (records) {
    records.forEach(function (record) {
        if (record.type === 'childList') {
            $(record.addedNodes)
                .find('input:not([type="hidden"])')
                .addBack('input:not([type="hidden"])')
                .each(addClearBtn);
        }
    });
});

observer.observe(document.body, {
    childList: true,
    subtree: true
});

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.