0
Отклонен

Не получается корректно интегрировать подсказки на страницу оформления заказа интернет-магазина на CS-Cart

Анонимный 6 лет назад обновлен Антон Жиянов 6 лет назад 2

Добрый день!


Не получается корректно встроить код с вашими подсказками на страницу оформления заказа моего интернет-магазина (на CS-Cart).


В ходе попыток и экспериментов:

а) Закачал файлы, подключаемые в вашем jQuery-плагине себе на сервер;

б) Создал такого Франкенштейна:


<script class="cm-ajax cm-ajax-force cm-ajax-full-render" type="text/javascript" src="/app/dadata/jquery/1.10.2/jquery.min.js" data-no-defer></script>
<script class="cm-ajax cm-ajax-force cm-ajax-full-render" type="text/javascript" src="/app/dadata/dist/js/jquery.suggestions.min.js" data-no-defer></script>
<link class="cm-ajax cm-ajax-force cm-ajax-full-render" rel="stylesheet" href="/app/dadata/dist/css/suggestions.min.css" data-no-defer>
<script class="cm-ajax cm-ajax-force" type="text/javascript" data-no-defer>
/**
 * Показывает индекс в отдельном поле
 */
function showPostalCode(suggestion) {
  $("#elm_29").val(suggestion.data.postal_code);
}
/**
 * Очищает индекс
 */
function clearPostalCode(suggestion) {
 $("#elm_29").val("");
}
function join(arr /*, separator */ ) {
 var separator = arguments.length > 1 ? arguments[1] : ", ";
 return arr.filter(function(n) {
 return n
 }).join(separator);
}
function makeAddressString(address) {
 if (address.settlement) {
 return join([
 address.city,
 address.settlement
 ])
 } else {
 return join([
 address.city,
 ])
 }
}
function formatResult(value, currentValue, suggestion) {
 var addressValue = makeAddressString(suggestion.data);
 suggestion.value = addressValue;
return addressValue;
}
function formatSelected(suggestion) {
 var addressValue = makeAddressString(suggestion.data);
return addressValue;
}
var 
token = "63aca8e5a32834498b49fadbbbc3d8fd69811ec4",
 type  = "ADDRESS",
 $city   = $("#elm_23"),
 $street = $("#elm_19");
// город и населенный пункт
$city.suggestions({
  token: token,
  type: type,
  hint: false,
  bounds: "city-settlement",
  formatResult: formatResult,
  formatSelected: formatSelected,
  onSelect: showPostalCode,
  onSelectNothing: clearPostalCode
});
// улица
$street.suggestions({
  token: token,
  type: type,
  hint: false,
  bounds: "street-house",
  constraints: $city,
  onSelect: showPostalCode,
  onSelectNothing: clearPostalCode
});
</script>


В CS-Cart страница оформления заказа состоит из четырех шагов - регистрация/авторизация (шаг 1), адрес доставки/адрес плательщика (шаг 2), выбор способа доставки, выбор способа оплаты. При загрузке страницы попадаешь на один из этих четырех шагов (в зависимости от заполненности профиля и сохраненных кук), остальные три шага подгружаются через ajax.

Соответственно, вставил этот код в шаблон второго шага, получилось следующее:


{if $show_email}
    <div class="ty-control-group">
        <label for="{$id_prefix}elm_email" class="cm-required cm-email">{__("email")}<i>*</i></label>
        <input type="text" id="{$id_prefix}elm_email" name="user_data[email]" size="32" value="{$user_data.email}" class="ty-input-text {$_class}" {$disabled_param} />
    </div>
{else}
{if $profile_fields.$section}
{if $address_flag}
    <div class="ty-profile-field__switch ty-address-switch clearfix">
        <div class="ty-profile-field__switch-label">{if $section == "S"}{__("shipping_same_as_billing")}{else}{__("text_billing_same_with_shipping")}{/if}</div>
        <div class="ty-profile-field__switch-actions">
            <input class="radio cm-switch-availability cm-switch-inverse cm-switch-visibility" type="radio" name="ship_to_another" value="0" id="sw_{$body_id}_suffix_yes" {if !$ship_to_another}checked="checked"{/if} /><label for="sw_{$body_id}_suffix_yes">{__("yes")}</label>
            <input class="radio cm-switch-availability cm-switch-visibility" type="radio" name="ship_to_another" value="1" id="sw_{$body_id}_suffix_no" {if $ship_to_another}checked="checked"{/if} /><label for="sw_{$body_id}_suffix_no">{__("no")}</label>
        </div>
    </div>
{else}
    <input type="hidden" name="ship_to_another" value="1" />
{/if}
{if ($address_flag && !$ship_to_another && ($section == "S" || $section == "B")) || $disabled_by_default}
    {assign var="disabled_param" value="disabled=\"disabled\""}
    {assign var="_class" value="disabled"}
    {assign var="hide_fields" value=true}
{else}
    {assign var="disabled_param" value=""}
    {assign var="_class" value=""}
{/if}
<div class="clearfix">
{if $body_id || $grid_wrap}
    <div id="{$body_id}" class="{if $hide_fields}hidden{/if}">
        <div class="{$grid_wrap}">
{/if}
{if !$nothing_extra}
    {include file="common/subheader.tpl" title=$title}
{/if}
{foreach from=$profile_fields.$section item=field name="profile_fields"}
    
{if $field.field_name && $field.is_default == 'Y'}
    {assign var="data_name" value="user_data"}
    {assign var="data_id" value=$field.field_name}
    {assign var="value" value=$user_data.$data_id}
{else}
    {assign var="data_name" value="user_data[fields]"}
    {assign var="data_id" value=$field.field_id}
    {assign var="value" value=$user_data.fields.$data_id}
{/if}
{assign var="skip_field" value=false}
{if $section == "S" || $section == "B"}
    {if $section == "S"}
        {assign var="_to" value="B"}
    {else}
        {assign var="_to" value="S"}
    {/if}
    {if !$profile_fields.$_to[$field.matching_id]}
        {assign var="skip_field" value=true}
    {/if}
{/if}
{hook name="profiles:profile_fields"}
<div class="ty-control-group ty-profile-field__item ty-{$field.class}">
<script class="cm-ajax cm-ajax-force" type="text/javascript" data-no-defer>
    function dadata(){
    var jqm = document.createElement('script'), jqs = document.createElement('script'), ssm = document.createElement('style');
 jqm.class = 'cm-ajax cm-ajax-force cm-ajax-full-render';
 jqm.type = 'text/javascript';
 jqm.async = true;
 jqm.src = '/app/dadata/jquery/1.10.2/jquery.min.js';
 jqs.class = 'cm-ajax cm-ajax-force cm-ajax-full-render'
 jqs.type = 'text/javascript';
 jqs.async = true;
 jqs.src = '/app/dadata/dist/js/jquery.suggestions.min.js';
 ssm.class = 'cm-ajax cm-ajax-force cm-ajax-full-render'
 ssm.rel = 'stylesheet';
 ssm.href = '/app/dadata/dist/css/suggestions.min.css'; 
 /**
 * Показывает индекс в отдельном поле
 */
 function showPostalCode(suggestion) {
   $("#elm_29").val(suggestion.data.postal_code);
 }
/**
 * Очищает индекс
 */
 function clearPostalCode(suggestion) {
 $("#elm_29").val("");
 }
 function join(arr /*, separator */ ) {
 var separator = arguments.length > 1 ? arguments[1] : ", ";
 return arr.filter(function(n) {
 return n
 }).join(separator);
 }
 
 function makeAddressString(address) {
 if (address.settlement) {
 return join([
 address.city,
 address.settlement
 ])
 } else {
 return join([
 address.city,
 ])
 }
 }
function formatResult(value, currentValue, suggestion) {
 var addressValue = makeAddressString(suggestion.data);
 suggestion.value = addressValue;
return addressValue;
 }
 function formatSelected(suggestion) {
 var addressValue = makeAddressString(suggestion.data);
return addressValue;
 }
 var 
 token = "63aca8e5a32834498b49fadbbbc3d8fd69811ec4",
 type  = "ADDRESS",
 $city   = $("#elm_23"),
 $street = $("#elm_19");
// город и населенный пункт
 $city.suggestions({
   token: token,
   type: type,
   hint: false,
   bounds: "city-settlement",
   formatResult: formatResult,
   formatSelected: formatSelected,
   onSelect: showPostalCode,
   onSelectNothing: clearPostalCode
 });
// улица
 $street.suggestions({
   token: token,
   type: type,
   hint: false,
   bounds: "street-house",
   constraints: $city,
   onSelect: showPostalCode,
   onSelectNothing: clearPostalCode
 });
 }
</script>
    {if $pref_field_name != $field.description || $field.required == "Y"}
        <label for="{$id_prefix}elm_{$field.field_id}" class="ty-control-group__title cm-profile-field {if $field.required == "Y"}cm-required{/if}{if $field.field_type == "P"} cm-phone{/if}{if $field.field_type == "Z"} cm-zipcode{/if}{if $field.field_type == "E"} cm-email{/if} {if $field.field_type == "Z"}{if $section == "S"}cm-location-shipping{else}cm-location-billing{/if}{/if}">{$field.description}</label>
    {/if}
    {if $field.field_type == "A"}  {* State selectbox *}
        {$_country = $settings.General.default_country}
        {$_state = $value|default:$settings.General.default_state}
        <select {if $field.autocomplete_type}x-autocompletetype="{$field.autocomplete_type}"{/if} id="{$id_prefix}elm_{$field.field_id}" class="ty-profile-field__select-state cm-state {if $section == "S"}cm-location-shipping{else}cm-location-billing{/if} {if !$skip_field}{$_class}{/if}" name="{$data_name}[{$data_id}]" {if !$skip_field}{$disabled_param nofilter}{/if}>
            <option value="">- {__("select_state")} -</option>
            {if $states && $states.$_country}
                {foreach from=$states.$_country item=state}
                    <option {if $_state == $state.code}selected="selected"{/if} value="{$state.code}">{$state.state}</option>
                {/foreach}
            {/if}
        </select><input {if $field.autocomplete_type}x-autocompletetype="{$field.autocomplete_type}"{/if} type="text" id="elm_{$field.field_id}_d" name="{$data_name}[{$data_id}]" size="32" maxlength="64" value="{$_state}" disabled="disabled" class="cm-state {if $section == "S"}cm-location-shipping{else}cm-location-billing{/if} ty-input-text hidden {if $_class}disabled{/if}"/>
    {elseif $field.field_type == "O"}  {* Countries selectbox *}
        {assign var="_country" value=$value|default:$settings.General.default_country}
        <select {if $field.autocomplete_type}x-autocompletetype="{$field.autocomplete_type}"{/if} id="{$id_prefix}elm_{$field.field_id}" class="ty-profile-field__select-country cm-country {if $section == "S"}cm-location-shipping{else}cm-location-billing{/if} {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if}" name="{$data_name}[{$data_id}]" {if !$skip_field}{$disabled_param nofilter}{/if}>
            {hook name="profiles:country_selectbox_items"}
            <option value="">- {__("select_country")} -</option>
            {foreach from=$countries item="country" key="code"}
            <option {if $_country == $code}selected="selected"{/if} value="{$code}">{$country}</option>
            {/foreach}
            {/hook}
        </select>
    
    {elseif $field.field_type == "C"}  {* Checkbox *}
        <input type="hidden" name="{$data_name}[{$data_id}]" value="N" {if !$skip_field}{$disabled_param nofilter}{/if} />
        <input type="checkbox" id="{$id_prefix}elm_{$field.field_id}" name="{$data_name}[{$data_id}]" value="Y" {if $value == "Y"}checked="checked"{/if} class="checkbox {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if}" {if !$skip_field}{$disabled_param nofilter}{/if} />
    {elseif $field.field_type == "T"}  {* Textarea *}
        <textarea {if $field.autocomplete_type}x-autocompletetype="{$field.autocomplete_type}"{/if} class="ty-input-textarea {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if}" id="{$id_prefix}elm_{$field.field_id}" name="{$data_name}[{$data_id}]" cols="32" rows="3" {if !$skip_field}{$disabled_param nofilter}{/if}>{$value}</textarea>
    
    {elseif $field.field_type == "D"}  {* Date *}
        {if !$skip_field}
            {include file="common/calendar.tpl" date_id="`$id_prefix`elm_`$field.field_id`" date_name="`$data_name`[`$data_id`]" date_val=$value extra=$disabled_param}
        {else}
            {include file="common/calendar.tpl" date_id="`$id_prefix`elm_`$field.field_id`" date_name="`$data_name`[`$data_id`]" date_val=$value}
        {/if}
    {elseif $field.field_type == "S"}  {* Selectbox *}
        <select {if $field.autocomplete_type}x-autocompletetype="{$field.autocomplete_type}"{/if} id="{$id_prefix}elm_{$field.field_id}" class="ty-profile-field__select {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if}" name="{$data_name}[{$data_id}]" {if !$skip_field}{$disabled_param nofilter}{/if}>
            {if $field.required != "Y"}
            <option value="">--</option>
            {/if}
            {foreach from=$field.values key=k item=v}
            <option {if $value == $k}selected="selected"{/if} value="{$k}">{$v}</option>
            {/foreach}
        </select>
    
    {elseif $field.field_type == "R"}  {* Radiogroup *}
        <div id="{$id_prefix}elm_{$field.field_id}">
            {foreach from=$field.values key=k item=v name="rfe"}
            <input class="radio {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if} {$id_prefix}elm_{$field.field_id}" type="radio" id="{$id_prefix}elm_{$field.field_id}_{$k}" name="{$data_name}[{$data_id}]" value="{$k}" {if (!$value && $smarty.foreach.rfe.first) || $value == $k}checked="checked"{/if} {if !$skip_field}{$disabled_param nofilter}{/if} /><span class="radio">{$v}</span>
            {/foreach}
        </div>
    {elseif $field.field_type == "N"}  {* Address type *}
        <input class="radio {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if} {$id_prefix}elm_{$field.field_id}" type="radio" id="{$id_prefix}elm_{$field.field_id}_residential" name="{$data_name}[{$data_id}]" value="residential" {if !$value || $value == "residential"}checked="checked"{/if} {if !$skip_field}{$disabled_param nofilter}{/if} /><span class="radio">{__("address_residential")}</span>
        <input class="radio {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if} {$id_prefix}elm_{$field.field_id}" type="radio" id="{$id_prefix}elm_{$field.field_id}_commercial" name="{$data_name}[{$data_id}]" value="commercial" {if $value == "commercial"}checked="checked"{/if} {if !$skip_field}{$disabled_param nofilter}{/if} /><span class="radio">{__("address_commercial")}</span>
    {else}  {* Simple input *}
        <input {if $field.autocomplete_type}x-autocompletetype="{$field.autocomplete_type}"{/if} type="text" id="{$id_prefix}elm_{$field.field_id}" name="{$data_name}[{$data_id}]" size="32" value="{$value}" class="ty-input-text {if !$skip_field}{$_class}{else}cm-skip-avail-switch{/if} {if $smarty.foreach.profile_fields.index == 0} cm-focus{/if}" {if !$skip_field}{$disabled_param nofilter}{/if} />
    {/if}
    {assign var="pref_field_name" value=$field.description}
</div>
{/hook}
{/foreach}
<script class="cm-ajax cm-ajax-force cm-ajax-full-render" type="text/javascript" src="/app/dadata/jquery/1.10.2/jquery.min.js" data-no-defer></script>
<script class="cm-ajax cm-ajax-force cm-ajax-full-render" type="text/javascript" src="/app/dadata/dist/js/jquery.suggestions.min.js" data-no-defer></script>
<link class="cm-ajax cm-ajax-force cm-ajax-full-render" rel="stylesheet" href="/app/dadata/dist/css/suggestions.min.css" data-no-defer>
<script class="cm-ajax cm-ajax-force" type="text/javascript" data-no-defer>
/**
 * Показывает индекс в отдельном поле
 */
function showPostalCode(suggestion) {
  $("#elm_29").val(suggestion.data.postal_code);
}
/**
 * Очищает индекс
 */
function clearPostalCode(suggestion) {
    $("#elm_29").val("");
}
function join(arr /*, separator */ ) {
 var separator = arguments.length > 1 ? arguments[1] : ", ";
 return arr.filter(function(n) {
 return n
 }).join(separator);
}
function makeAddressString(address) {
 if (address.settlement) {
 return join([
 address.city,
 address.settlement
 ])
 } else {
 return join([
 address.city,
 ])
 }
}
function formatResult(value, currentValue, suggestion) {
 var addressValue = makeAddressString(suggestion.data);
 suggestion.value = addressValue;
return addressValue;
}
function formatSelected(suggestion) {
 var addressValue = makeAddressString(suggestion.data);
return addressValue;
}
var 
token = "63aca8e5a32834498b49fadbbbc3d8fd69811ec4",
 type  = "ADDRESS",
 $city   = $("#elm_23"),
 $street = $("#elm_19");
// город и населенный пункт
$city.suggestions({
  token: token,
  type: type,
  hint: false,
  bounds: "city-settlement",
  formatResult: formatResult,
  formatSelected: formatSelected,
  onSelect: showPostalCode,
  onSelectNothing: clearPostalCode
});
// улица
$street.suggestions({
  token: token,
  type: type,
  hint: false,
  bounds: "street-house",
  constraints: $city,
  onSelect: showPostalCode,
  onSelectNothing: clearPostalCode
});
</script>
{if $body_id || $grid_wrap}
        </div>
    </div>
{/if}
</div>
{/if}
{/if}


В итоге:

а) Если загружать страницу оформления заказа и попадать сразу на второй шаг - все работает отлично. Так бывает, если например пользователь уже залогинен, но у него в профиле не указаны данные по адресу доставки;

б) Если загружать чекаут и попадать на первый, третий или четвертый шаг, и уже с помощью ajax-а возвращаться на второй - то работать все перестает и страница виснет. Консоль выдает следующее:


Image 846


Уверен, что должно быть какое-то простое решение, как с этим бороться. Может сможете помочь?

Ответ

Ответ
На рассмотрении

Добрый день! Несколько вопросов:

  1. Код инициализации подсказок дублируется дважды. Один раз внутри хука profiles:profile_fields, второй — без хуков внизу шаблона. Зачем?
  2. В каких случаях вызывается хук profiles:profile_fields?
  3. Дайте, пожалуйста, ссылку на сайт, где можно увидеть описанное поведение в действии.
Ответ
На рассмотрении

Добрый день! Несколько вопросов:

  1. Код инициализации подсказок дублируется дважды. Один раз внутри хука profiles:profile_fields, второй — без хуков внизу шаблона. Зачем?
  2. В каких случаях вызывается хук profiles:profile_fields?
  3. Дайте, пожалуйста, ссылку на сайт, где можно увидеть описанное поведение в действии.

Сервис поддержки клиентов работает на платформе UserEcho