如何通过其属性代码在React中绘制可配置的产品?

发布于 2025-01-10 02:58:46 字数 10345 浏览 2 评论 0原文

三天来我一直在尝试编写一个通用代码,它允许我们选择一些选项,例如,按尺寸、颜色、材质等选择衬衫,这样如果没有这样的选项,那么这个按钮就是禁用,但一半有效。 谁可以帮助我,也许是建议什么的? 下面是我的代码。

function ConfigurableFilters ({ handleChangeConfig, configurablesData, state }) {

  const isDisabled = (e, code) => {
    let products = [...e.products];
    for(let attr of configurablesData.attributes) {
      if(attr.code === code) {
        break
      }
      products = products.filter(prod => state.selectedConfigs[attr.code].products.includes(prod))
       state.selectedConfigs[attr.code].id)
    }
    return !products.length
  }


  return (
    <div className="configurable-attributes">
      {
        configurablesData.attributes.map((attr) => {
          if (attr.options.length > 1) {
            if (attr.code !== 'color') {
              return (
                <div className="attr_fms attr_space">
                  <div className="attr_label_size">{attr.label}</div>
                  {
                    attr.code !== 'color'
                    && attr.options.length > 0
                    && !attr.options[0].swatch_value
                    && (
                      <div className="other-list-main-fms">
                        {attr.options.map((e, i) => {
                          return (
                            <label
                              htmlFor={attr.code + e.id}
                              key={i}
                              id={e.id + attr.code}
                            >
                            <span className="other-list__input">
                              <span className="other-radio__body">
                                <input
                                  id={attr.code + e.id}
                                  className="other-radio__input"
                                  type="radio"
                                  name={attr.code}
                                  value={e.id}
                                  checked={state.selectedConfigs[attr.code].id === e.id}
                                  onChange={() => {
                                    handleChangeConfig(
                                      e.products,
                                      attr.id,
                                      attr.code,
                                      e,
                                    )
                                  }}
                                  disabled={isDisabled(e, attr.code)}
                                />
                              </span>
                            </span>
                              <span className="other-list__title">
                              {e.label}
                            </span>
                            </label>
                          )
                        })}
                      </div>
                    )}
                </div>
              )
            } else {
              return (
                <div className="attr_color_fms attr_space">
                  <div className="attr_label_size">{attr.label}</div>
                  {
                    attr.options
                    && attr.options.length > 1
                    && (
                      <div className="color-attr_fm">
                        {
                          attr.options.map((e, i) => {
                            return (
                              <div
                                key={i}
                                className="filter-color__item"
                                id={e.id + attr.code}
                              >
                          <span
                            className={classNames(
                              'filter-color__check input-check-color',
                              {
                                'input-check-color--white':
                                  colorType(e.swatch_value) === 'white',
                                'input-check-color--light':
                                  colorType(e.swatch_value) === 'light',
                              },
                            )}
                            style={{ color: `${e.label}`.toLowerCase() }}
                          >
                            <label className="input-check-color__body">
                              <input
                                id={attr.code + e.id}
                                className="input-check-color__input"
                                name={attr.code}
                                type="radio"
                                value={e.id}
                                checked={state.selectedConfigs[attr.code].id === e.id}
                                onChange={() => {
                                  handleChangeConfig(
                                    e.products,
                                    attr.id,
                                    attr.code,
                                    e,
                                  )
                                }}
                                disabled={isDisabled(e, attr.code)}
                              />
                              <span className="input-check-color__box"/>
                              <Check12x9Svg className="input-check-color__icon"/>
                              <span className="input-check-color__stick"/>
                            </label>
                          </span>
                              </div>
                            )
                          })
                        }
                      </div>
                    )
                  }
                </div>
              )
            }
          }
        })
      }
    </div>
  )
}


export default ConfigurableFilters

这是我的示例屏幕截图

这是我的标准情况

我想为每个组合得到类似的东西,在这种情况下我没有 <50 & <100,所以它们被禁用,但是它可以处理错误,但并不总是适用于其他产品

在这个产品中它不起作用...我没有“M”尺寸,但它已启用

“M”尺寸必须禁用,但处于活动状态

任何建议或想法??

这是我的可配置数据

{
  "attributes": [
    {
      "id": 23,
      "code": "color",
      "label": "Color",
      "options": [
        {
          "_id": "6215cd906648a738081c765b",
          "id": 1,
          "admin_name": "Red",
          "attribute_id": 23,
          "sort_order": 1,
          "label": "Red",
          "translations": [
            {
              "locale": "en",
              "name": null
            },
            {
              "locale": "ru",
              "name": null
            }
          ],
          "products": [
            119,
            123,
            125
          ]
        },
        {
          "_id": "6215cd906648a738081c765c",
          "id": 2,
          "admin_name": "Green",
          "attribute_id": 23,
          "sort_order": 2,
          "label": "Green",
          "translations": [
            {
              "locale": "en",
              "name": null
            },
            {
              "locale": "ru",
              "name": null
            }
          ],
          "products": [
            120,
            122,
            124,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    },
    {
      "id": 24,
      "code": "size",
      "label": "Size",
      "options": [
        {
          "_id": "6215cd906648a738081c7660",
          "id": 6,
          "admin_name": "S",
          "attribute_id": 24,
          "sort_order": 1,
          "label": "S",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            119,
            120,
            123,
            124
          ]
        },
        {
          "_id": "6215cd906648a738081c7661",
          "id": 7,
          "admin_name": "M",
          "attribute_id": 24,
          "sort_order": 2,
          "label": "M",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            122,
            125,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    },
    {
      "id": 29,
      "code": "Papertype",
      "label": "Paper type",
      "options": [
        {
          "_id": "6215cd906648a738081c7669",
          "id": 15,
          "admin_name": "Type 1",
          "attribute_id": 29,
          "sort_order": 1,
          "label": "Type 1",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            119,
            120,
            122
          ]
        },
        {
          "_id": "6215cd906648a738081c766a",
          "id": 16,
          "admin_name": "Type 2",
          "attribute_id": 29,
          "sort_order": 2,
          "label": "Type 2",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            123,
            124,
            125,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    }
  ],
  "chooseText": "Choose an option",
  "index": {
    "119": {
      "23": "1",
      "24": "6",
      "29": "15"
    },
    "120": {
      "23": "2",
      "24": "6",
      "29": "15"
    },
    "122": {
      "23": "2",
      "24": "7",
      "29": "15"
    },
    "123": {
      "23": "1",
      "24": "6",
      "29": "16"
    },
    "124": {
      "23": "2",
      "24": "6",
      "29": "16"
    },
    "125": {
      "23": "1",
      "24": "7",
      "29": "16"
    },
    "126": {
      "23": "2",
      "24": "7",
      "29": "16"
    }
  }
}

for 3 days now I have been trying to write a universal code that will allow us to select some options, for example, shirts by their size, color, material, etc., so that if there is no such option, then this button is disabled, but half works.
Who can help me, maybe advice or something??
here is my code below.

function ConfigurableFilters ({ handleChangeConfig, configurablesData, state }) {

  const isDisabled = (e, code) => {
    let products = [...e.products];
    for(let attr of configurablesData.attributes) {
      if(attr.code === code) {
        break
      }
      products = products.filter(prod => state.selectedConfigs[attr.code].products.includes(prod))
       state.selectedConfigs[attr.code].id)
    }
    return !products.length
  }


  return (
    <div className="configurable-attributes">
      {
        configurablesData.attributes.map((attr) => {
          if (attr.options.length > 1) {
            if (attr.code !== 'color') {
              return (
                <div className="attr_fms attr_space">
                  <div className="attr_label_size">{attr.label}</div>
                  {
                    attr.code !== 'color'
                    && attr.options.length > 0
                    && !attr.options[0].swatch_value
                    && (
                      <div className="other-list-main-fms">
                        {attr.options.map((e, i) => {
                          return (
                            <label
                              htmlFor={attr.code + e.id}
                              key={i}
                              id={e.id + attr.code}
                            >
                            <span className="other-list__input">
                              <span className="other-radio__body">
                                <input
                                  id={attr.code + e.id}
                                  className="other-radio__input"
                                  type="radio"
                                  name={attr.code}
                                  value={e.id}
                                  checked={state.selectedConfigs[attr.code].id === e.id}
                                  onChange={() => {
                                    handleChangeConfig(
                                      e.products,
                                      attr.id,
                                      attr.code,
                                      e,
                                    )
                                  }}
                                  disabled={isDisabled(e, attr.code)}
                                />
                              </span>
                            </span>
                              <span className="other-list__title">
                              {e.label}
                            </span>
                            </label>
                          )
                        })}
                      </div>
                    )}
                </div>
              )
            } else {
              return (
                <div className="attr_color_fms attr_space">
                  <div className="attr_label_size">{attr.label}</div>
                  {
                    attr.options
                    && attr.options.length > 1
                    && (
                      <div className="color-attr_fm">
                        {
                          attr.options.map((e, i) => {
                            return (
                              <div
                                key={i}
                                className="filter-color__item"
                                id={e.id + attr.code}
                              >
                          <span
                            className={classNames(
                              'filter-color__check input-check-color',
                              {
                                'input-check-color--white':
                                  colorType(e.swatch_value) === 'white',
                                'input-check-color--light':
                                  colorType(e.swatch_value) === 'light',
                              },
                            )}
                            style={{ color: `${e.label}`.toLowerCase() }}
                          >
                            <label className="input-check-color__body">
                              <input
                                id={attr.code + e.id}
                                className="input-check-color__input"
                                name={attr.code}
                                type="radio"
                                value={e.id}
                                checked={state.selectedConfigs[attr.code].id === e.id}
                                onChange={() => {
                                  handleChangeConfig(
                                    e.products,
                                    attr.id,
                                    attr.code,
                                    e,
                                  )
                                }}
                                disabled={isDisabled(e, attr.code)}
                              />
                              <span className="input-check-color__box"/>
                              <Check12x9Svg className="input-check-color__icon"/>
                              <span className="input-check-color__stick"/>
                            </label>
                          </span>
                              </div>
                            )
                          })
                        }
                      </div>
                    )
                  }
                </div>
              )
            }
          }
        })
      }
    </div>
  )
}


export default ConfigurableFilters

here is my example screenshot

this is my standard case

I want to get something like this for each combination, in this situation I dont have <50 & <100, so they are disabled, but it works with bugs, not always works for other products

In this product it is not working... I don't have "M" size, but it is enabled

"M" size must be disabled but it is active

Any suggestions or ideas??

and this is my configurableData

{
  "attributes": [
    {
      "id": 23,
      "code": "color",
      "label": "Color",
      "options": [
        {
          "_id": "6215cd906648a738081c765b",
          "id": 1,
          "admin_name": "Red",
          "attribute_id": 23,
          "sort_order": 1,
          "label": "Red",
          "translations": [
            {
              "locale": "en",
              "name": null
            },
            {
              "locale": "ru",
              "name": null
            }
          ],
          "products": [
            119,
            123,
            125
          ]
        },
        {
          "_id": "6215cd906648a738081c765c",
          "id": 2,
          "admin_name": "Green",
          "attribute_id": 23,
          "sort_order": 2,
          "label": "Green",
          "translations": [
            {
              "locale": "en",
              "name": null
            },
            {
              "locale": "ru",
              "name": null
            }
          ],
          "products": [
            120,
            122,
            124,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    },
    {
      "id": 24,
      "code": "size",
      "label": "Size",
      "options": [
        {
          "_id": "6215cd906648a738081c7660",
          "id": 6,
          "admin_name": "S",
          "attribute_id": 24,
          "sort_order": 1,
          "label": "S",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            119,
            120,
            123,
            124
          ]
        },
        {
          "_id": "6215cd906648a738081c7661",
          "id": 7,
          "admin_name": "M",
          "attribute_id": 24,
          "sort_order": 2,
          "label": "M",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            122,
            125,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    },
    {
      "id": 29,
      "code": "Papertype",
      "label": "Paper type",
      "options": [
        {
          "_id": "6215cd906648a738081c7669",
          "id": 15,
          "admin_name": "Type 1",
          "attribute_id": 29,
          "sort_order": 1,
          "label": "Type 1",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            119,
            120,
            122
          ]
        },
        {
          "_id": "6215cd906648a738081c766a",
          "id": 16,
          "admin_name": "Type 2",
          "attribute_id": 29,
          "sort_order": 2,
          "label": "Type 2",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            123,
            124,
            125,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    }
  ],
  "chooseText": "Choose an option",
  "index": {
    "119": {
      "23": "1",
      "24": "6",
      "29": "15"
    },
    "120": {
      "23": "2",
      "24": "6",
      "29": "15"
    },
    "122": {
      "23": "2",
      "24": "7",
      "29": "15"
    },
    "123": {
      "23": "1",
      "24": "6",
      "29": "16"
    },
    "124": {
      "23": "2",
      "24": "6",
      "29": "16"
    },
    "125": {
      "23": "1",
      "24": "7",
      "29": "16"
    },
    "126": {
      "23": "2",
      "24": "7",
      "29": "16"
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文