<blockquote>
<p>Why doesn't <code>s-preserve</code> work? Where have I gone wrong?</p>
</blockquote>
<p>Your question is very vague, but I'll try to answer as best I can. The <code>s-preserve</code> attribute (see <a href="https://htmx.org/attributes/hx-preserve/" rel="nofollow noreferrer">https://htmx.org/attributes/hx-preserve/</a>) will preserve the element, provided it has a unique ID. So looking at your code, the search input field element will be preserved, as expected, when the component is re-rendered.</p>
<p>Now to decode your question, it could be that the element is not being preserved in the way you expect – perhaps it is losing focus? This would likely be due to how <code>hx-preserve</code> works, but that would be a htmx-specific question. Restructuring your code so that you can use <code>s-replace=&quot;#articles-and-pagination&quot;</code> would be optimal, resorting to JavaScript to replace other elements on the page if necessary, see <a href="https://putyourlightson.com/plugins/sprig#javascript" rel="nofollow noreferrer">https://putyourlightson.com/plugins/sprig#javascript</a></p>

CC BY-SA 4.0
2022-04-26T11:09:41.357Z
Thanks for your answer. I have considered changing the code to fit sprig better and then just re-positioning it afterwards using `flex order`, but since I asked this question, the clients priorities have shifted so I haven't had time to try it out. Definitely will eventually though. All in all, sprig is fantastic and a fantastic time-saver.
InanisAtheos
CC BY-SA 4.0
2022-04-12T17:24:45.980Z
2022-04-12T17:24:45.980Z
Ben Croker
<p>I have a relatively simple search of a section called <code>articles</code>. Each entry within articles has a category assigned. I've named the category <code>animal</code>.</p>
<p>Layout is as follows:</p>
<ol>
<li>Header</li>
<li>Search/filtering section</li>
<li>Articles container</li>
<li>Pagination container</li>
</ol>
<p>The problem I'm having, is that the search field gets replaced whenever the sprigboard updates. The only way to stop this, is to wrap the <code>#articleContainer</code> and <code>#articlePagination</code> into a div (<code>#articles-and-pagination</code>) and use <code>s-replace=&quot;#articles-and-pagination&quot;</code>. However, this doesn't work in this case because I need to also replace the contents of the Header, which is above the search field.</p>
<p>So the next solution was to use <code>s-preserve=&quot;true&quot;</code> on the search field itself, but that seems to have absolutely no effect because it still gets replaced on each ajax load.</p>
<p>Below is the full code I've written thus far. I realise that parts of it is quite messy. I haven't gotten near to finalizing this :).</p>
<pre class="lang-html prettyprint-override"><code>{% set section  = 'articles' %}
{% set search   = search ?? '' %}
{% set animal   = animal ?? '' %}
{% set page     = page ?? 1 %}

{% set filters = {
    search: search,
    relatedTo: animal,
} %}

{% set entryQuery = craft.entries(filters|merge({
    section: section,
    limit: 21,
})) %}

{% set animals = craft.categories.group('animal').all() %}
{% set pageInfo = sprig.paginate(entryQuery, page) %}
{% set entries = pageInfo.pageResults %}
{% do sprig.pushUrl('?' ~ filters|merge({
    page: page
})|url_encode) %}

{% set pageTitle = '&lt;h1&gt;' ~ 'Articles and Guides'|t ~ '&lt;/h1&gt;' %}
{% if animal is defined and animal != '' %}
    {% set animalObject = craft.categories.id(animal).one() %}
    {% set pageTitle = '&lt;h1&gt;' ~ animalObject.title ~ '&lt;/h1&gt;' %}
    {% if animalObject.textArea|length %}
        {% set supportingText = '&lt;p class=&quot;text-lg m-auto max-w-xl&quot;&gt;' ~ animalObject.textArea ~ '&lt;/p&gt;' %}
    {% endif %}
{% else %}
    {% if entry is defined and entry.redactorSimple|length %}
        {% set pageTitle = entry.redactorSimple %}
    {% endif %}
{% endif %}

&lt;div&gt;
    &lt;section class=&quot;pt-5 pb-5 bg-fv-vlight-beige relative&quot;&gt;
        &lt;header class=&quot;container text-center relative z-10&quot;&gt;
            &lt;div id=&quot;articleTitleContainer&quot; class=&quot;max-w-xl m-auto c-redactor&quot;&gt;
                {{ pageTitle|raw }}
                {{ supportingText is defined ? supportingText|raw : '' }}
            &lt;/div&gt;
        &lt;/header&gt;
    &lt;/section&gt;

    {# ARTICLES SEARCH BAR #}
    &lt;section class=&quot;bg-fv-white py-4&quot;&gt;
        &lt;div class=&quot;max-w-2xl mx-auto px-3&quot;&gt;
            &lt;form class=&quot;flex justify-center flex-wrap&quot;&gt;
                &lt;div class=&quot;article-search-category-wrapper&quot; id=&quot;animal&quot; sprig &gt;
                    &lt;div class=&quot;item category-all&quot;&gt;
                        &lt;label&gt;
                            &lt;input type=&quot;radio&quot; id=&quot;c_all&quot; name=&quot;animal&quot; value=&quot;&quot; {% if animal == '' %} checked {% endif %} &gt;
                            &lt;div class=&quot;icon category-all&quot;&gt;&lt;/div&gt;
                            &lt;span&gt;{{ 'All'|t }}&lt;/span&gt;
                        &lt;/label&gt;
                    &lt;/div&gt;
                    
                    {% for categoryOption in animals %}
                        {% if categoryOption.id is not null %}
                            {% set categoryUrl = siteUrl ~ categoryOption.uri %}
                            {% set catID = categoryOption.id %}
                            &lt;div class=&quot;item category-{{ catID }}&quot;&gt;
                                &lt;label&gt;
                                    {% set entryCount = craft.entries.relatedTo(categoryOption).count() %}
                                    {% if entryCount &gt; 0 %}
                                        &lt;input
                                            class=&quot;filter-button&quot; 
                                            type=&quot;radio&quot; 
                                            id=&quot;c_{{ catID }}&quot; 
                                            name=&quot;animal&quot; 
                                            value=&quot;{{ catID }}&quot;
                                        &gt;
                                        &lt;div class=&quot;icon category-{{ categoryOption.id }}&quot;&gt;&lt;/div&gt;
                                        &lt;span&gt;{{ categoryOption.title }}&lt;/span&gt;
                                    {% endif %}
                                &lt;/label&gt;
                            &lt;/div&gt;
                        {% endif %}
                    {% endfor %}

                &lt;/div&gt;

                &lt;div class=&quot;article-search-input&quot; id=&quot;article-search-input-wrapper&quot;&gt;
                    {% set placeholder = 'Search for'|t ~ '...' %}
                    {% set searchPrefix = '' %}

                    &lt;input
                        sprig
                        s-trigger=&quot;keyup changed delay:300ms&quot;
                        s-preserve=&quot;true&quot;
                        name=&quot;search&quot;
                        id=&quot;search&quot;

                        class=&quot;p-3 text-xl border-2 rounded w-full md:h-full mb-2 md:mb-0 outline-none focus:border-fv-pink&quot;
                        placeholder=&quot;{{ placeholder }}&quot;
                        value=&quot;{{ search ?? '' }}&quot;
                        aria-label=&quot;{{ 'Search articles'|t }}&quot;
                    &gt;
                &lt;/div&gt;

                &lt;div class=&quot;article-search-button&quot;&gt;
                    &lt;button type=&quot;submit&quot; class=&quot;bg-fv-pink hover:bg-fv-more-pink transition-all w-full text-white md:h-full p-3 rounded text-xl &quot;&gt;
                        &lt;span class=&quot;font-bold&quot;&gt;{{ 'Search'|t }}&lt;/span&gt;
                    &lt;/button&gt;
                &lt;/div&gt;
            &lt;/form&gt;
        &lt;/div&gt;
    &lt;/section&gt;

    {# LISTING SECTION #}
    &lt;div id=&quot;articles-and-pagination&quot;&gt;
        &lt;section class=&quot;pb-4 md:pb-5 pt-4 relative&quot;&gt;
            &lt;div class=&quot;container&quot;&gt;
                &lt;div class=&quot;articles articlesContainer max-w-2xl mx-auto&quot; id=&quot;articleContainer&quot;&gt;
                    {% for article in entries %}
                        &lt;a href=&quot;{{ article.url }}&quot; class=&quot;article-card&quot;&gt;

                            &lt;div class=&quot;article-card__image&quot; style=&quot;position: relative; overflow:hidden;&quot;&gt;IMAGE HERE&lt;/div&gt;

                            &lt;div class=&quot;article-card__inner&quot;&gt;
                                &lt;div&gt;
                                    &lt;h2 class=&quot;article-card__title text-lg&quot;&gt;{{ article.title }}&lt;/h2&gt;

                                    {% if article.articleIntro|length &gt;= 200 %}
                                        &lt;p class=&quot;article-card__intro&quot;&gt;{{ article.articleIntro|slice(0, 200) ~ '...' }}&lt;/p&gt;
                                    {% else %}
                                        &lt;p class=&quot;article-card__intro&quot;&gt;{{ article.articleIntro }}&lt;/p&gt;
                                    {% endif %}
                                &lt;/div&gt;

                                &lt;span class=&quot;article-card__link&quot;&gt;{{ 'Read article'|t }}&lt;/span&gt;
                            &lt;/div&gt;
                        &lt;/a&gt;
                    {% endfor %}
                &lt;/div&gt;
                
            &lt;/div&gt;
        &lt;/section&gt;

        &lt;section class=&quot;mb-4 mt-4&quot;&gt;
            &lt;div class=&quot;max-w-2xl mx-auto px-3&quot; id=&quot;articlePagination&quot;&gt;

                &lt;div class=&quot;text-center text-sm &quot;&gt;
                    {{ 'Showing page'|t }}
                    {{ pageInfo.currentPage }}
                    {{ 'of'|t }}
                    {{ pageInfo.totalPages }}
                &lt;/div&gt;
                
                &lt;ul class=&quot;flex flex-wrap justify-center w-auto font-sans&quot;&gt;
                    {% if page &gt; 1 %}
                        &lt;li&gt;
                            &lt;a sprig s-val:page=&quot;{{ page - 1 }}&quot; href=&quot;#&quot; 
                                class=&quot;block m-1 border rounded px-0 py-2 border-transparent&quot;&gt;
                                PREVIOUS
                            &lt;/a&gt;
                        &lt;/li&gt;
                    {% endif %}
                    {% for pageNumber in pageInfo.dynamicRange(5) %}
                        &lt;li&gt;
                            &lt;a sprig s-val:page=&quot;{{ pageNumber }}&quot; href=&quot;#&quot; 
                                class=&quot;block m-1 border rounded px-3 py-2 {{ pageNumber == page ? 'border-fv-blue text-white font-bold bg-fv-blue' : 'border-fv-grey' }} &quot;&gt;
                                {{ pageNumber }}
                            &lt;/a&gt;
                        &lt;/li&gt;
                    {% endfor %}
                    {% if page &lt; pageInfo.totalPages %}
                        &lt;li&gt;
                            &lt;a sprig s-val:page=&quot;{{ page + 1 }}&quot; href=&quot;#&quot; 
                                class=&quot;block m-1 border rounded px-0 py-2 border-transparent&quot;&gt;
                                NEXT
                            &lt;/a&gt;
                        &lt;/li&gt;
                    {% endif %}
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/section&gt;
    &lt;/div&gt;
&lt;/div&gt;

</code></pre>
<p>Edit: To clarify the question; Why doesn't <code>s-preserve</code> work? Where have I gone wrong? I realize it's difficult to test of course, but I'm hoping someone with more experience with sprig can see some glaring mistake :)</p>

CC BY-SA 4.0
2022-04-11T11:22:29.733Z
The `s-preserve` attribute should do the trick. You haven't asked a question though, so it's impossible to give you an answer...
Ben Croker
CC BY-SA 4.0
2022-04-11T13:51:44.777Z
@BenCroker Sorry, I thought the question was implied. I've clarified it
InanisAtheos
<search><pagination><plugin-sprig>
Sprig replacing search field even with s-preserve="true"
# Sprig replacing search field even with s-preserve="true"

(Asked by: username_0 on 2022-04-04)

I have a relatively simple search of a section called articles. Each entry within articles has a category assigned. I've named the category animal.
Layout is as follows:

Header
Search/filtering section
Articles container
Pagination container

The problem I'm having, is that the search field gets replaced whenever the sprigboard updates. The only way to stop this, is to wrap the #articleContainer and #articlePagination into a div (#articles-and-pagination) and use s-replace="#articles-and-pagination". However, this doesn't work in this case because I need to also replace the contents of the Header, which is above the search field.
So the next solution was to use s-preserve="true" on the search field itself, but that seems to have absolutely no effect because it still gets replaced on each ajax load.
Below is the full code I've written thus far. I realise that parts of it is quite messy. I haven't gotten near to finalizing this :).
{% set section  = 'articles' %}
{% set search   = search ?? '' %}
{% set animal   = animal ?? '' %}
{% set page     = page ?? 1 %}

{% set filters = {
    search: search,
    relatedTo: animal,
} %}

{% set entryQuery = craft.entries(filters|merge({
    section: section,
    limit: 21,
})) %}

{% set animals = craft.categories.group('animal').all() %}
{% set pageInfo = sprig.paginate(entryQuery, page) %}
{% set entries = pageInfo.pageResults %}
{% do sprig.pushUrl('?' ~ filters|merge({
    page: page
})|url_encode) %}

{% set pageTitle = '' ~ 'Articles and Guides'|t ~ '' %}
{% if animal is defined and animal != '' %}
    {% set animalObject = craft.categories.id(animal).one() %}
    {% set pageTitle = '' ~ animalObject.title ~ '' %}
    {% if animalObject.textArea|length %}
        {% set supportingText = '' ~ animalObject.textArea ~ '' %}
    {% endif %}
{% else %}
    {% if entry is defined and entry.redactorSimple|length %}
        {% set pageTitle = entry.redactorSimple %}
    {% endif %}
{% endif %}


    
        
            
                {{ pageTitle|raw }}
                {{ supportingText is defined ? supportingText|raw : '' }}
            
        
    

    {# ARTICLES SEARCH BAR #}
    
        
            
                
                    
                        
                            
                            
                            {{ 'All'|t }}
                        
                    
                    
                    {% for categoryOption in animals %}
                        {% if categoryOption.id is not null %}
                            {% set categoryUrl = siteUrl ~ categoryOption.uri %}
                            {% set catID = categoryOption.id %}
                            
                                
                                    {% set entryCount = craft.entries.relatedTo(categoryOption).count() %}
                                    {% if entryCount > 0 %}
                                        
                                        
                                        {{ categoryOption.title }}
                                    {% endif %}
                                
                            
                        {% endif %}
                    {% endfor %}

                

                
                    {% set placeholder = 'Search for'|t ~ '...' %}
                    {% set searchPrefix = '' %}

                    
                

                
                    
                        {{ 'Search'|t }}
                    
                
            
        
    

    {# LISTING SECTION #}
    
        
            
                
                    {% for article in entries %}
                        

                            IMAGE HERE

                            
                                
                                    {{ article.title }}

                                    {% if article.articleIntro|length >= 200 %}
                                        {{ article.articleIntro|slice(0, 200) ~ '...' }}
                                    {% else %}
                                        {{ article.articleIntro }}
                                    {% endif %}
                                

                                {{ 'Read article'|t }}
                            
                        
                    {% endfor %}
                
                
            
        

        
            

                
                    {{ 'Showing page'|t }}
                    {{ pageInfo.currentPage }}
                    {{ 'of'|t }}
                    {{ pageInfo.totalPages }}
                
                
                
                    {% if page > 1 %}
                        
                            
                                PREVIOUS
                            
                        
                    {% endif %}
                    {% for pageNumber in pageInfo.dynamicRange(5) %}
                        
                            
                                {{ pageNumber }}
                            
                        
                    {% endfor %}
                    {% if page < pageInfo.totalPages %}
                        
                            
                                NEXT
                            
                        
                    {% endif %}
                
            
        
    



Edit: To clarify the question; Why doesn't s-preserve work? Where have I gone wrong? I realize it's difficult to test of course, but I'm hoping someone with more experience with sprig can see some glaring mistake :)

**Tags:** search, pagination, plugin-sprig
> **Comments:**
> **username_1**: The `s-preserve` attribute should do the trick. You haven't asked a question though, so it's impossible to give you an answer...  
> **username_0**: @BenCroker Sorry, I thought the question was implied. I've clarified it  

---

## 1 answers

### Answer by username_1 on 2022-04-12. Score: 2 | Accepted answer

> Why doesn't `s-preserve` work? Where have I gone wrong?

Your question is very vague, but I'll try to answer as best I can. The `s-preserve` attribute (see <https://htmx.org/attributes/hx-preserve/>) will preserve the element, provided it has a unique ID. So looking at your code, the search input field element will be preserved, as expected, when the component is re-rendered.

Now to decode your question, it could be that the element is not being preserved in the way you expect – perhaps it is losing focus? This would likely be due to how `hx-preserve` works, but that would be a htmx-specific question. Restructuring your code so that you can use `s-replace="#articles-and-pagination"` would be optimal, resorting to JavaScript to replace other elements on the page if necessary, see <https://putyourlightson.com/plugins/sprig#javascript>

> **Comments:**
> **username_0**: Thanks for your answer. I have considered changing the code to fit sprig better and then just re-positioning it afterwards using `flex order`, but since I asked this question, the clients priorities have shifted so I haven't had time to try it out. Definitely will eventually though. All in all, sprig is fantastic and a fantastic time-saver.  

---

