Home
Wiki
Home
Wiki
  1. 2. Components
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ShoppingListsButton
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Shipping
      • ShoppingLists
      • ShoppingListsNavbar
      • Toast
      • Users
      • VariantContent
      • WishlistButton
      • Services
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • Overview
        • theme.js
      • Css / Scss
        • Overview
        • ThemeClasses
    • 5. SDK
      • Overview
      • LiquidGlobals
      • ServicesSDK
  1. 2. Components

ChangePassword

Purpose#

The ChangePassword component renders the “Change password” form and submits the new password using the theme services layer.
It includes:
Password + Confirm Password inputs
Client-side validation (required fields + password strength rules + match validation)
Show/hide password toggle
Toast feedback for success/failure
Redirect to /login on success

Inputs (model contract)#

Model shape (storefront example)#

{
  "name": "ChangePassword",
  "view": "Default",
  "section": "SectionA",
  "settings": {
    "id": "Component Id",
    "section": "SectionA",
    "type": "NoirChangePassword",
    "name": "ChangePassword",
    "configuredInContentApi": true,
    "view": "Default",
    "displayName": "",
    "cssClass": "Sample cssClass"
  },
  "translations": {
    "changePassword": "Sample translation",
    "buttonText": "Sample translation",
    "errorEmptyField": "Sample translation",
    "...": "..."
  }
}

Required fields#

settings.id
Used for wrapper id: comp-{{ id }}

Optional fields#

settings.cssClass
Applied to wrapper only when non-empty and not (UNDEFINED).

JavaScript#

Global object#

The component exposes an Alpine-ready object:
It’s used directly from the template via:
x-data="changepassworddefault"

State fields (what they represent)#

fields: []
Cached list of form inputs (all [name] fields except disabled + submit).
errors: {}
Per-field error code mapping:
"required" / "weak" / "unmatched" / "" (empty string means no error)
isSending: false
Used to disable UI / show loading state while submitting.
errorUpLowCase, errorLength, errorSymbolNum
Password strength breakdown flags (used to show the “weak password must…” checklist).
Advice
errors is the “single source of truth” for messages shown via x-show="errors[fieldName] === ..." in Liquid.
The 3 strength flags are reset when validating the main password field (not confirm). Keep that behavior so the checklist doesn’t “stick” between attempts.

init()#

What it does
Collects all inputs inside the component root (this.$el) that have a name attribute:
excludes disabled fields
excludes submit inputs
Stores them in this.fields.
Attaches blur listeners so each field validates when the user leaves it:
field.addEventListener("blur", () => this.validateField(field))
Advice
This relies on this.$el being the correct component root (Alpine’s element). If you move x-data to a different wrapper, the selector scope will change.
If you dynamically add/remove fields later, you’ll need to re-run init() or write logic to refresh fields.

validateField(field)#

What it does
Validates one field and updates:
this.errors[field.name]
the field CSS classes (valid / invalid)
the status icon element (.icon-state)
the password strength breakdown flags (for password fields)
1) Reset password-strength breakdown flags (only for the main password field)
If the field is not a confirm field (!field.name.includes("confirm")), it resets:
errorUpLowCase, errorLength, errorSymbolNum
2) Required rule
If field is required and empty:
errorType = "required"
valid = false
3) Password rules
It locates both password inputs:
input[name="change-password"]
input[name="change-confirm-password"]
If the field is the main password (not confirm):
Validates each requirement with separate regexes:
uppercase + lowercase (unicode-aware): reUpLowCase
length >= 8: reLength
at least one number + one symbol: reSymbolNum
Sets per-requirement flags (errorUpLowCase, etc.) so the UI can show exactly what’s missing.
Also sets a combined “weak” error type via reWeak:
if it fails, sets:
errorType = "weak"
If the confirm password has a value, it re-validates confirm as well:
this.validateField(confirmPassword)
If the field is the confirm password:
Checks match:
if confirm != password:
valid = false
errorType = "unmatched"
4) Persist error state + update UI classes/icons
Writes:
this.errors[field.name] = errorType
Toggles classes on the field:
invalid when not valid
valid when valid
Updates .icon-state:
invalid → shows warning icon class
valid → shows check icon class
Advice
field.closest("div") assumes each input sits inside a div that’s the styling container. If markup changes, class toggling may stop working; keep markup consistent.
Regex reSymbolNum and reWeak define “symbol” as a specific ASCII set. If you want broader symbol support (e.g., non-ASCII punctuation), you’ll need to adjust the regex.
Because it calls itself for confirm validation, be careful when modifying confirm logic to avoid recursion loops. Current code is safe (one-way trigger).

toggleVisibility(event)#

What it does
Implements show/hide password:
Uses the checkbox id convention:
checkbox id: toggle-<inputId>
input id: <inputId>
Finds the input:
document.getElementById(inputId)
Switches input type:
"password" ↔ "text"
Updates checkbox state and icon classes:
ic-eye-off ↔ ic-preview
Advice
This depends on strict id naming between checkbox and input. If you rename ids in Liquid, update this logic.
For accessibility: the template already triggers this on click and on Enter keypress. Keep both handlers.

updateFormValidity()#

What it does
Returns true only if every field:
has no error code in this.errors[field.name], and
is not empty when required
Implementation:
iterates all this.fields
checks err and requiredEmpty
Advice
This is purely client-side validation; it doesn’t check server-side token validity or password reuse rules.

clearForm()#

What it does
Resets the form UI and state:
clears value for each field
removes valid / invalid classes
resets .icon-state classes
clears the errors object
Advice
Called only on successful submission. If you want a “Reset form” button, this is the method to call.

checkForm(successMessage, errorMessageFail) (async)#

What it does
Main submit handler:
1.
Clears toast messages:
Alpine.store("toast").removeAll()
2.
Validates all fields:
this.fields.forEach(field => this.validateField(field))
3.
Stops if invalid:
if (!this.updateFormValidity()) return;
4.
Sets sending flag:
this.isSending = true
5.
Builds payload:
token: last path segment of window.location.href
NewPassword: #change-password value
ValidatePassword: #change-confirm-password value
6.
Calls API through theme services:
servicesreusabledefault.changePassword(info)
7.
On failure:
shows error toast with errorMessageFail
clears isSending
returns
8.
On success:
clearForm()
shows success toast with successMessage
clears isSending
redirects to /login after 1 second
Advice
Token extraction uses the full URL string and takes everything after the last /.
If your URL can contain query params (e.g. ...?x=y), the token will include them. Safer alternative:
new URL(window.location.href).pathname.split("/").pop()
The redirect delay is hardcoded to 1000ms. If you want the user to have more time to read the toast, increase it or redirect after the toast closes.
Consider wrapping the service call with try/finally so isSending is always reset even if an unexpected exception occurs.

Global Alpine stores (used by ChangePassword)#

$store.toast#

Used for user feedback:
clears existing messages before validation/submit
shows error toast when API fails
shows success toast when API succeeds
Common pattern:
Alpine.store("toast").removeAll();
Alpine.store("toast").add(message, "ic-warning", "error");

Dependencies#

Alpine.js (for x-data, x-show, event handlers)
$store.toast
servicesreusabledefault.changePassword(...) (theme services API)
Browser supports standard DOM APIs (the component uses querySelector/getElementById)

Notes#

The component depends on the reset token being present in the URL. The token is read as the last segment of window.location.href.
On success it redirects to /login after 1 second.
Password validation accepts unicode lowercase/uppercase letters and checks for symbol/number requirements.

Extras#

Template behavior (Liquid + Alpine)#

The form is initialized with:
x-data="changepassworddefault"
On submit it calls:
@submit.prevent="checkForm(successMessage, errorMessage)"
The password visibility toggle is handled via checkbox inputs that call:
toggleVisibility($event)
(on click and on Enter key press for accessibility)
Validation messages are shown conditionally using:
x-show="errors['change-password'] === 'required'"
x-show="errors['change-password'] === 'weak'"
x-show="errors['change-confirm-password'] === 'unmatched'"
Modified at 2026-04-14 13:18:56
Previous
CategoriesList
Next
Checkout
Built with