Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-26T11:09:41.357Z
Answers.Text: 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.
Answers.UserDisplayName: InanisAtheos
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-04-12T17:24:45.980Z
Answers.LastActivityDate: 2022-04-12T17:24:45.980Z
Answers.UserDisplayName: Ben Croker
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-04-11T11:22:29.733Z
Comments.Text: The `s-preserve` attribute should do the trick. You haven't asked a question though, so it's impossible to give you an answer...
Comments.UserDisplayName: Ben Croker
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-04-11T13:51:44.777Z
Comments.Text: @BenCroker Sorry, I thought the question was implied. I've clarified it
Comments.UserDisplayName: InanisAtheos
Tags: <search><pagination><plugin-sprig>
Title: Sprig replacing search field even with s-preserve="true"
ThreadText: # 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:
  
  1. Header
  2. Search/filtering section
  3. Articles container
  4. 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 :).
  
  ```html
  {% 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 = '<h1>' ~ 'Articles and Guides'|t ~ '</h1>' %}
  {% if animal is defined and animal != '' %}
      {% set animalObject = craft.categories.id(animal).one() %}
      {% set pageTitle = '<h1>' ~ animalObject.title ~ '</h1>' %}
      {% if animalObject.textArea|length %}
          {% set supportingText = '<p class="text-lg m-auto max-w-xl">' ~ animalObject.textArea ~ '</p>' %}
      {% endif %}
  {% else %}
      {% if entry is defined and entry.redactorSimple|length %}
          {% set pageTitle = entry.redactorSimple %}
      {% endif %}
  {% endif %}
  
  <div>
      <section class="pt-5 pb-5 bg-fv-vlight-beige relative">
          <header class="container text-center relative z-10">
              <div id="articleTitleContainer" class="max-w-xl m-auto c-redactor">
                  {{ pageTitle|raw }}
                  {{ supportingText is defined ? supportingText|raw : '' }}
              </div>
          </header>
      </section>
  
      {# ARTICLES SEARCH BAR #}
      <section class="bg-fv-white py-4">
          <div class="max-w-2xl mx-auto px-3">
              <form class="flex justify-center flex-wrap">
                  <div class="article-search-category-wrapper" id="animal" sprig >
                      <div class="item category-all">
                          <label>
                              <input type="radio" id="c_all" name="animal" value="" {% if animal == '' %} checked {% endif %} >
                              <div class="icon category-all"></div>
                              <span>{{ 'All'|t }}</span>
                          </label>
                      </div>
                      
                      {% for categoryOption in animals %}
                          {% if categoryOption.id is not null %}
                              {% set categoryUrl = siteUrl ~ categoryOption.uri %}
                              {% set catID = categoryOption.id %}
                              <div class="item category-{{ catID }}">
                                  <label>
                                      {% set entryCount = craft.entries.relatedTo(categoryOption).count() %}
                                      {% if entryCount > 0 %}
                                          <input
                                              class="filter-button" 
                                              type="radio" 
                                              id="c_{{ catID }}" 
                                              name="animal" 
                                              value="{{ catID }}"
                                          >
                                          <div class="icon category-{{ categoryOption.id }}"></div>
                                          <span>{{ categoryOption.title }}</span>
                                      {% endif %}
                                  </label>
                              </div>
                          {% endif %}
                      {% endfor %}
  
                  </div>
  
                  <div class="article-search-input" id="article-search-input-wrapper">
                      {% set placeholder = 'Search for'|t ~ '...' %}
                      {% set searchPrefix = '' %}
  
                      <input
                          sprig
                          s-trigger="keyup changed delay:300ms"
                          s-preserve="true"
                          name="search"
                          id="search"
  
                          class="p-3 text-xl border-2 rounded w-full md:h-full mb-2 md:mb-0 outline-none focus:border-fv-pink"
                          placeholder="{{ placeholder }}"
                          value="{{ search ?? '' }}"
                          aria-label="{{ 'Search articles'|t }}"
                      >
                  </div>
  
                  <div class="article-search-button">
                      <button type="submit" class="bg-fv-pink hover:bg-fv-more-pink transition-all w-full text-white md:h-full p-3 rounded text-xl ">
                          <span class="font-bold">{{ 'Search'|t }}</span>
                      </button>
                  </div>
              </form>
          </div>
      </section>
  
      {# LISTING SECTION #}
      <div id="articles-and-pagination">
          <section class="pb-4 md:pb-5 pt-4 relative">
              <div class="container">
                  <div class="articles articlesContainer max-w-2xl mx-auto" id="articleContainer">
                      {% for article in entries %}
                          <a href="{{ article.url }}" class="article-card">
  
                              <div class="article-card__image" style="position: relative; overflow:hidden;">IMAGE HERE</div>
  
                              <div class="article-card__inner">
                                  <div>
                                      <h2 class="article-card__title text-lg">{{ article.title }}</h2>
  
                                      {% if article.articleIntro|length >= 200 %}
                                          <p class="article-card__intro">{{ article.articleIntro|slice(0, 200) ~ '...' }}</p>
                                      {% else %}
                                          <p class="article-card__intro">{{ article.articleIntro }}</p>
                                      {% endif %}
                                  </div>
  
                                  <span class="article-card__link">{{ 'Read article'|t }}</span>
                              </div>
                          </a>
                      {% endfor %}
                  </div>
                  
              </div>
          </section>
  
          <section class="mb-4 mt-4">
              <div class="max-w-2xl mx-auto px-3" id="articlePagination">
  
                  <div class="text-center text-sm ">
                      {{ 'Showing page'|t }}
                      {{ pageInfo.currentPage }}
                      {{ 'of'|t }}
                      {{ pageInfo.totalPages }}
                  </div>
                  
                  <ul class="flex flex-wrap justify-center w-auto font-sans">
                      {% if page > 1 %}
                          <li>
                              <a sprig s-val:page="{{ page - 1 }}" href="#" 
                                  class="block m-1 border rounded px-0 py-2 border-transparent">
                                  PREVIOUS
                              </a>
                          </li>
                      {% endif %}
                      {% for pageNumber in pageInfo.dynamicRange(5) %}
                          <li>
                              <a sprig s-val:page="{{ pageNumber }}" href="#" 
                                  class="block m-1 border rounded px-3 py-2 {{ pageNumber == page ? 'border-fv-blue text-white font-bold bg-fv-blue' : 'border-fv-grey' }} ">
                                  {{ pageNumber }}
                              </a>
                          </li>
                      {% endfor %}
                      {% if page < pageInfo.totalPages %}
                          <li>
                              <a sprig s-val:page="{{ page + 1 }}" href="#" 
                                  class="block m-1 border rounded px-0 py-2 border-transparent">
                                  NEXT
                              </a>
                          </li>
                      {% endif %}
                  </ul>
              </div>
          </section>
      </div>
  </div>
  
  ```
  
  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**: @username_1 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.  
  
  ---
  
  