Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Помогите решить проблему! (https://javascript.ru/forum/dom-window/69995-pomogite-reshit-problemu.html)

rdPavel 02.08.2017 11:49

Помогите решить проблему!
 
Доброго дня спецы!
Два дня не могу решить проблему.

На странице, с помощью скрытого инпута ->

<input type="hidden" name="ID" value="<?php echo esc_attr( $listing->ID ); ?>" />

Создаются поля, выпадающие списки, произвольные поля и так далее

Одно из них ->
<select name="cp_state" id="cp_state" class="dropdownlist required">

Как мне программно присвоить этому <select name="cp_state" id="cp_state" обработчик onchange="CityList(this)

Пробовал присвоить в файле custom-forms.php
$field_class = ( $result->field_req ) ? 'dropdownlist required' : 'dropdownlist';
$args = array( 'name' => $result->field_name, 'id' => $result->field_name, 'class' => $field_class, 'onchange' => 'CityList(this)' );

Но тогда этот обработчик во всех dropdownlist, а мне нужен только name="cp_state" id="cp_state"

Нужно всего лишь сделать вот так:
<select name="cp_state" id="cp_state"class="dropdownlist required" onchange="CityList(this)"> и всё.

А вот этот <select name="cp_state" id="cp_state" class="dropdownlist required"> штатный, создается самим движком.

Как еще можно сделать?
Подскажите!

rdPavel 02.08.2017 11:55

Я уже думал создать еще один <select name="cp_state2" id="cp_state2" class="dropdownlist required" с обработчиком onchange="CityList(this)"> СКРЫТЫЙ

и копировать или вставлять данные с cp_state в cp_state2
Но этот вариант как то не очень, так как в дальнейшем будет много зависимых селектов.

Nexus 02.08.2017 12:08

rdPavel, открой файл, который создает тебе эти формы и посмотри можно ли там свои атрибуты элементам присваивать или нет.
Во втором случае допили сценарий, либо нужный select руками на странице пропиши.

rdPavel 02.08.2017 12:17

Nexus,

Файл form-listing-details.php

<form name="mainform" id="mainform" class="form_step" action="<?php echo appthemes_get_step_url(); ?>" method="post" enctype="multipart/form-data">
<?php wp_nonce_field( $action ); ?>

<ol>
<span class="form-fields">
<li>
<div class="labelwrapper"><label><?php _e( 'Category', APP_TD ); ?></label></div>
<div class="ad-static-field"><strong><?php echo $category->name; ?></strong>&nbsp;&nbsp;<small><a href="<?php echo $select_category_url; ?>"><?php _e( '(change)', APP_TD ); ?></a></small></div>
</li>
<?php cp_show_form( $category->term_id, $listing ); ?>
</span>
<center><p class="btn1">
<input type="submit" name="step1" id="step1" class="btn_orange" value="<?php _e( 'Continue &rsaquo;&rsaquo;', APP_TD ); ?>" / >
</p></center>
</ol>

<input type="hidden" name="action" value="<?php echo esc_attr( $action ); ?>" />
<input type="hidden" name="ID" value="<?php echo esc_attr( $listing->ID ); ?>" />

Как раз последний <?php echo esc_attr( $listing->ID и формирует все эти поля, куда только я не совал onchange="CityList(this)" - срабатывает только у cp_state.
Если я его просто в открытом коде в браузере вставлю, всё чотко работает. До перезагрузки страницы.

rdPavel 02.08.2017 12:25

Цитата:

Сообщение от Nexus (Сообщение 460368)
rdPavel, открой файл, который создает тебе эти формы и посмотри можно ли там свои атрибуты элементам присваивать или нет.
Во втором случае допили сценарий, либо нужный select руками на странице пропиши.

В том то и дело, что можно свой селект создать и не парится.
Но задача использовать штатный cp_state так как он по всей системе, и в отборах, и фильтрах и в поиске и так далее

Nexus 02.08.2017 12:39

rdPavel, я бы так не стал делать, но это же wordpress))
ob_start();
cp_show_form( $category->term_id, $listing );
$select=ob_get_contents();
ob_end_clean();
$select=str_replace('<select ','<select onchange="CityList(this);" ',$select);

echo $select;

rdPavel 02.08.2017 12:43

Nexus,
https://drive.google.com/open?id=0Bz...XVOT2hJS2VpQms

Nexus 02.08.2017 12:47

rdPavel, а куда мой код был помещен?
PS. По-моему проще подключить к странице скрипт (судя по тому, что в атрибут вставляется наименование пользовательской функции, он уже подключен), в котором обратиться к селекту и повесить на него обработчик.

Nexus 02.08.2017 12:49

rdPavel,
<form name="mainform" id="mainform" class="form_step" action="<?php echo appthemes_get_step_url(); ?>" method="post" enctype="multipart/form-data">
<?php wp_nonce_field( $action ); ?>

<ol>
<span class="form-fields">
<li>
<div class="labelwrapper"><label><?php _e( 'Category', APP_TD ); ?></label></div>
<div class="ad-static-field"><strong><?php echo $category->name; ?></strong>&nbsp;&nbsp;<small><a href="<?php echo $select_category_url; ?>"><?php _e( '(change)', APP_TD ); ?></a></small></div>
</li>
<?php 
    ob_start();
    cp_show_form( $category->term_id, $listing );
    $select=ob_get_contents();
    ob_end_clean();
    $select=str_replace('<select ','<select onchange="CityList(this);" ',$select);

    echo $select;
?>
</span>
<center><p class="btn1">
<input type="submit" name="step1" id="step1" class="btn_orange" value="<?php _e( 'Continue &rsaquo;&rsaquo;', APP_TD ); ?>" / >
</p></center>
</ol>

<input type="hidden" name="action" value="<?php echo esc_attr( $action ); ?>" />
<input type="hidden" name="ID" value="<?php echo esc_attr( $listing->ID ); ?>" />

rdPavel 02.08.2017 12:52

Nexus,
в <form name="mainform"

rdPavel 02.08.2017 13:16

Nexus,

Да всё чотко код приписывает параметр для Селект.
Одна проблема он приписывает его для всех Селект кто в форме.
А как сделать чтобы только для cp_state, другим не нужно?

Для всех можно еще вот здесь прописать:
в файле custom-forms.php
$field_class = ( $result->field_req ) ? 'dropdownlist required' : 'dropdownlist';
$args = array( 'name' => $result->field_name, 'id' => $result->field_name, 'class' => $field_class, 'onchange' => 'CityList(this)' );

Пробовал так, он на всех Селектах приписывает onchange="CityList(this);"

Nexus 02.08.2017 13:35

rdPavel, верни все как было, а перед функцией CityList напиши следующее:

window.onload=function(){
    window.document.getElementById('cp_state').onchange=function(e){
        CityList(e.target);
    };
};
if(window.document.readyState=='complete')
    window.dispatchEvent(new Event('load'));

rdPavel 02.08.2017 13:40

Nexus,

Я ваш код обязательно проверю.
Я прошлый немного доработал, в принципе работает отлично
Одну строчку изменил:
$select=str_replace('cp_state','cp_state" onchange="getCityList(this);" ',$select);
echo $select;

Весь смысл в двойной " после cp_state

rdPavel 02.08.2017 13:41

Или всё таки вернуть всё обратно и:

window.onload=function(){
window.document.getElementById('cp_state').onchang e=function(e){
CityList(e.target);
};
};
if(window.document.readyState=='complete')
window.dispatchEvent('load',new Event('load'));

Nexus 02.08.2017 13:49

rdPavel, не мне решать, но лучше заюзать второй вариант, правда я его не тестил.

rdPavel 02.08.2017 14:28

Nexus,

Код второй что-то не идет...
Спасибо большое за идею и направление в решении проблемы.

Nexus 02.08.2017 15:23

rdPavel, методу dispatchEvent передается только 1 аргумент - экземпляр "класса" Event, свой комментарий я поправил.

rdPavel 02.08.2017 16:17

Nexus,

Всё чотко, большое спасибо!
В коде в браузере даже аргумента не видно, но он работает. :)

Подскажите хорошую книжку по JS и PHP, надо бы углубляться, ну и разумеется практика и практика.

Nexus 02.08.2017 16:45

rdPavel, к моему стыду книг я посоветовать не могу, ибо ни одну даже не начинал читать.
Возможно кто-нибудь другой вам что посоветует.

rdPavel 03.08.2017 13:14

Nexus,

Добрый день!
Можете подсказать из-за чего могут конфликтовать эти два кода.
Один отключу второй работает и на оборот.
Эти оба на одной форме.

Обработчик cp_state.js
var ajax = new Array();

window.onload=function(){
window.document.getElementById('cp_state').onchange=function(e){
  getCityList(e.target);
   };
};
if(window.document.readyState=='complete')
window.dispatchEvent(new Event('load'));


function getCityList(sel)
{
	var countryCode = sel.options[sel.selectedIndex].value;
	document.getElementById('cp_region').options.length = 0;
	if(countryCode.length>0){
		var index = ajax.length;
		ajax[index] = new sack();
		
		ajax[index].requestFile = 'http://***/sel/baza/cp_state.php?countryCode='+countryCode;
		ajax[index].onCompletion = function(){ createCities(index) };
		ajax[index].runAJAX();
	}
}

function createCities(index)
{
	var obj = document.getElementById('cp_region');
	eval(ajax[index].response);	
}



Обработчик cp_avto.js
var ajax = new Array();

window.onload=function(){
window.document.getElementById('cp_id_387').onchange=function(e){
  getAvtoList(e.target);
   };
};
if(window.document.readyState=='complete')
window.dispatchEvent(new Event('load'));


function getAvtoList(sel)
{
	var countryCode2 = sel.options[sel.selectedIndex].value;
	document.getElementById('cp_id_928').options.length = 0;
	if(countryCode2.length>0){
		var index = ajax.length;
		ajax[index] = new sack();
		
		ajax[index].requestFile = 'http://***/sel/baza/cp_avto.php?countryCode2='+countryCode2;
		ajax[index].onCompletion = function(){ createCities2(index) };
		ajax[index].runAJAX();
	}
}

function createCities2(index)
{
	var obj = document.getElementById('cp_id_928');
	eval(ajax[index].response);	
}


База, у каждого своя, может её в общую согнать?

Nexus 03.08.2017 13:42

rdPavel, тут написана причина:
https://learn.javascript.ru/introduc...войство

rdPavel 03.08.2017 18:39

Да

rdPavel 03.08.2017 19:13

Nexus,

Спасибо за инфу!
Почитал, почитал, пока еще не могу догнать точное решение, буду разбираться.
Нужно просто Ваш код доработать...

rdPavel 03.08.2017 20:35

Nexus,

Браузер пишет Uncaught TypeError: невозможно прочитать свойство undefined неопределенного
В HTMLSelectElement.getAvtoList (cp_avto.js: 9)

var countryCode = sel.options[sel.selectedIndex].value;

rdPavel 04.08.2017 08:00

Rise,
Да нет, это перевод.

rdPavel 04.08.2017 08:18

Nexus,
Не могу понять, в одном месте пишет:
Методы addEventListener и removeEventListener являются современным способом назначить или удалить обработчик, и при этом позволяют использовать сколько угодно любых обработчиков.

В другом месте:
addEventListener() для одного и того же объекта с теми же самыми аргументами не дает никакого эффекта - функция-обработчик регистрируется только один раз и повторные вызовы не влияют на порядок вызова обработчиков.

Чего то я недопонимаю :( :-E

Nexus 04.08.2017 09:23

rdPavel, скорее всего речь идет об этом:
<div id="block"></div>
<script>var block=document.getElementById('block'),
i=2;
func=function(){alert(++i);},
block.addEventListener('click',function(){alert(1);},false);
block.addEventListener('click',function(){alert(2);},false);
block.addEventListener('click',func,false);
block.addEventListener('click',func,false);

block.dispatchEvent(new Event('click'));
</script>

Алерт будет вызван только трижды со значениями 1-3, четвертого вызова не произойдет.
Строки 5-6 - навешивание уникальных анонимных функций в кач-ве обработчика.
Строки 7-8 - навешивание одной и той же функции на один и тот же элемент, и на одно и то же событие.

Суть в том, что в строках 5-6 функции-обработчики уникальны, а в строках 7-8 в кач-ве обработчика выступает одна и та же функция, записанная в переменную.

rdPavel 04.08.2017 10:15

Nexus,

Я приблизительно понимаю о чем речь, но не могу догнать как склеить и реализовать с моими данными.

Еще вопрос:
Почему вот это срабатывает:
<script>
cp_id_387.onclick = function() { alert("Привет"); };
</script>

а

cp_id_387.onclick = function() { onchange="getAvtoList(this)"; };
cp_id_387.onclick = function() { getAvtoList(this); };
cp_id_387.onclick = function() { getAvtoList; };

Ноль эмоций...

Уже что-то запутался я :blink:

rdPavel 04.08.2017 10:28

Короче только такое нашел решение:
Больше в голову ничего не лезет, может я зациклился

<?php
ob_start();
cp_show_form( $category->term_id, $listing );
$select=ob_get_contents();
ob_end_clean();
$select=str_replace('cp_id_387','cp_id_387" onchange="getAvtoList(this)',$select);
$select=str_replace('cp_state','cp_state" onchange="getCityList(this)',$select);
echo $select;
?>

Оба поля Селекта работают на ура.

Не знаю насколько это правильно но пока так.
Нужно проверить на всех браузерах.

Nexus 04.08.2017 10:35

rdPavel, потому что у тебя там бред написан.
cp_id_387.onclick = function() { onchange="getAvtoList(this)"; };
cp_id_387.onclick = function() { getAvtoList(this); };
cp_id_387.onclick = function() { getAvtoList; };

Строка 1 - Навешиваешь обработчик на событие «click», обработчик перезаписывает значение свойство «onchange» глобального объекта «window» (а было ли свойство вообще объявлено?).
Строка 2 - перезаписываешь обработчик события «click» элемента, тут почти все верно. В твоём контексте, я уверен, this будет эквивалентно window (поправьте, если ошибаюсь).
Строка 3 - еще раз перезаписываешь обработчик события «click» элемента. Сам обработчик - чушь. Даже не знаю как это прокомментировать...

Чтобы навесить несколько обработчиков на 1 событие используй метод «addEventListener».
В первой строке ты попытался (вероятно) повесить обработчик на событие «change», должно было получиться так:
cp_id_387.onchange=function(e){getAvtoList(e.target);};//Или с addEventListener

Во второй строке, чтобы передать функции «getAvtoList» сущность, в отношении которой было произведено событие, нужно было получить событие и обратиться к его свойству «target», т.е. примерно так:
cp_id_387.onclick=function(e){getAvtoList(e.target);};

Nexus 04.08.2017 10:37

Цитата:

Сообщение от rdPavel
Не знаю насколько это правильно но пока так.
Нужно проверить на всех браузерах.

Ты вносишь изменения на стороне сервера, в любом браузере с включенным js 100% будет вызвана функция "getAvtoList".

ksa 04.08.2017 10:39

Цитата:

Сообщение от Nexus
Строка 2 - перезаписываешь обработчик события «click» элемента, тут почти все верно. В твоём контексте, я уверен, this будет эквивалентно window (поправьте, если ошибаюсь).

Все верно. :yes:

ksa 04.08.2017 10:40

Цитата:

Сообщение от Nexus
Чтобы навесить несколько обработчиков на 1 событие используй метод «addEventListener».

Или в одном делать все, что нужно. :)

rdPavel 09.08.2017 21:42

Nexus,

cp_id_387.onchange=function(e){getAvtoList(e.targe t);};
Функция повешена на cp_id_387.

Настраиваемые поля:

1. cp_id_387
Тип поля - раскрывающийся список;
Значения полей - объекты забиты, через запятую (Марка авто, порядка 271 шт.).

2. cp_id_928
Тип поля - раскрывающийся список;
Значения полей - пуст, объекты забиты в файле cp_avto.php в виде массива (Модель авто, порядка 4309 шт.), активация через getAvtoList

Вроде всё работает, НО при заполнений формы и нажатием "Далее", выходит ошибка "Ошибка: поле "Модель" недопустимо."

Такое ощущение что при отправке оно становится пустым.
Или он почему-то не отправляет данные с cp_id_928.

Браузер не выявил ошибок!
Мне кажется, что созданный селект (cp_id_928) - пустой в списке значений.
Как быть не знаю!

Nexus 10.08.2017 07:43

Цитата:

Сообщение от rdPavel
Такое ощущение что при отправке оно становится пустым.
Или он почему-то не отправляет данные с cp_id_928.

Смотри что на сервер отправляется.
«Панель разработчика», вкладка «Network».

rdPavel 10.08.2017 10:27

Nexus,

Добрый день!

Вот эти строки в документе отправки, вроде как данные есть

------WebKitFormBoundaryUHC6anEyShzgEYQk
Content-Disposition: form-data; name="cp_id_387"

Fiat

------WebKitFormBoundaryUHC6anEyShzgEYQk
Content-Disposition: form-data; name="cp_id_928"

a1300

Nexus 10.08.2017 10:42

Цитата:

Сообщение от rdPavel (Сообщение 461190)
Nexus,

Добрый день!

Вот эти строки в документе отправки, вроде как данные есть

Если данные отправляются, значит нужно смотреть как сервер их обрабатывает и проверяет на корректность.

rdPavel 10.08.2017 11:05

Nexus,

Еще одна интересная штука!
Попробовал убрать required с cp_id_928, всё вроде поле не обязательно, один хрен пишет "Ошибка: поле "Модель" недопустимо."

Другой момент:

Нажимаю "Далее", поле Марка содержит данные, а поле Модель пустое, пока через Марку не активирую обработчик
Модели не появляются.

rdPavel 10.08.2017 17:08

Как можно заставить что бы сессия сохраняла выбранное значение в cp_id_928, по сути форма не отправляет данные на базу, так как в форме не заполнено поле cp_id_928.
Не пойму что он делает перед отправкой, но он не может достать выбранное значение и поэтому в cp_id_928 вставляет пустое и выдает ошибку.

Вот блин не задача.

Просто моя задача сделать из штатных настраиваемых полей, которые создаются по средствам движка, зависимые поля или связанные поля.
Короче вот и встал я в ступор.

rdPavel 10.08.2017 19:40

Вот что другой браузер пишет после отправки формы:

[Deprecation] Calling Element.createShadowRoot() for an element which already hosts a shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details.


Часовой пояс GMT +3, время: 03:32.