Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   при выборе радиокнопки снималась другая (https://javascript.ru/forum/dom-window/27052-pri-vybore-radioknopki-snimalas-drugaya.html)

nikki4 01.04.2012 16:18

при выборе радиокнопки снималась другая
 
Добрый день!
Как сделать следующее? -
Есть 3 группы радиокнопок
Нужно чтобы можно было выбрать либо 1 либо 2+3
т.е. при выборе элемента из группы с именем 1 снимались кружки с 2 и 3 и наоборот при выборе 2 или 3, снимался кружок с 1 группы

Как такое делается на js?
(его вообще не знаю, попробовал погуглить, почитать справочник, но что-то не работает..)

nikki4 04.04.2012 13:03

вот форма.. а то наверное не понятно объяснил, так лучше:
Код HTML

    <fieldset style="position:absolute;margin:10px 0 0 300px">
    <legend>группа 1</legend>
    <input type="radio" name="two_01" value="1" id="1">1<br>
    <input type="radio" name="two_01" value="2" id="2">2<br>
    <input type="radio" name="two_01" value="3" id="3">3<br>
    </fieldset>
    <fieldset style= "width:200px;">
    <legend>группа 2</legend>
    <input type="radio" name="0" value="1" id="4">4<br>
    <input type="radio" name="0" value="2" id="5">5<br>
    <input type="radio" name="0" value="3" id="6">6</label><br>
    </fieldset>
    <fieldset style= "width:200px;">
    <legend>группа 3</legend>
    <input type="radio" name="1" value="1" id="7>7<br>
    <input type="radio" name="1" value="2" id="8">8<br>
    <input type="radio" name="1" value="3" id="9">9<br>
    </fieldset>


и надо, чтоб тот блок справа если был выбран, то те что слева снять значения и наоборот. т.е. либо слева стоит либо справа

GuardCat 04.04.2012 17:02

Предлагаю добавить фиелдсетам класс. Можно будет в рамках одной страницы объединять разные группы.

Вот пример. Функции при запуске передаётся класс тех тегов fieldset, радиокнопки внутри которых будут взаимно исключать выбор друг друга.
function originGroups(classForTest) {
  var 
    radiobuttons = document.querySelectorAll("fieldset." + classForTest + " input[type=radio]"),
    fieldsets = document.querySelectorAll("fieldset." + classForTest),
    x
  ;
  
  function unchecker(e) { //Это пришьём на клик к каждому полю fieldset
    e = e || window.event;
    var x, target = e.target || e.srcElement;
    if(target.type != "radio") return false;
    for(x = 0; x < radiobuttons.length; x++) {
      if (radiobuttons[x].parentNode !== this) {
        radiobuttons[x].checked = false;
      }
    }
  }
  
  for(x = 0; x < fieldsets.length; x++) {
    fieldsets[x].onclick = unchecker;
  }
}
originGroups("onlyIt");
Живой пример.

Хотя, честное слово, проще всем нужным радиокнопкам дать одно имя, независимо от того в каких они фиелдсетах. И ориентироваться по их id или другим параметрам.

nikki4 04.04.2012 19:39

в js вообще не понимаю :(
можно пожалуйста это подредактировать, так чтоб было как просил?
в том примере что выше, там можно выбрать только 1 группу, а надо бы, чтобы либо 1 либо 2+3. Т.е. либо 2 слева, либо 1 справа могли быть выбраны.

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

GuardCat 05.04.2012 11:03

Невнимательно прочитал, извиняюсь. Получилось громоздко, но нет уже ни времени ни желания оптимизировать:
function RadioController() {
  var 
    x, queryString, r,
    fieldsets = document.querySelectorAll("." + Array.prototype.join.call(arguments, ", ."))
  ;

  for(x = 0; x < fieldsets.length; x++) {
    queryString = "";
    for(y = 0; y < arguments.length; y++) {
      if (fieldsets[x].className === arguments[y]) continue;
      if (queryString.indexOf(arguments[y]) != -1) continue;
      queryString += " ." + arguments[y] + " input[type=radio], "
    }
    queryString = queryString.replace(/, $/, "");
    fieldsets[x].setAttribute("data-classes", queryString);
    fieldsets[x].onclick = RadioController.uncheckAnother;
  }
    
}
RadioController.uncheckAnother = function(e) {
  var target, x, radios;
  e = e || window.event;
  target = e.target || e.srcElement;
  
  if (target.type !== "radio") return false;
  
  radios = document.querySelectorAll(this.getAttribute("data-classes"));
  
  for(x = 0; x < radios.length; x++) {
    radios[x].checked = false;
  }
}

Вы назначаете группам классы. Создаёте экземпляр моего класса и передаёте ему класснеймы фиелдсетов, выбор радиокнопок в которых должен исключать друг друга. Пристрелите меня, но проще не скажу. Можно передавать не две группы, а сколько угодно. В качестве бонуса, будут учитываться динамически добавленные радиокнопки.

Для понимания проще, наверное, посмотреть пример.
Пример с тремя группами.

nikki4 05.04.2012 14:01

спасибо огромное! )
как раз то, что надо. только есть еще один вопросик.
Цитата:

Создаёте экземпляр моего класса
я не совсем понимаю что это значит, а тем более совсем не понимаю как это делать, однако посмотрев на код, догадался сделать так и заработало как надо!
var
          x, queryString, r, r2, r3, r4 и т.д.
.....
          r = new RadioController("oneGroup01", "twoGroup0");
	  r2 = new RadioController("oneGroup12", "twoGroup1");
	  r3 = new RadioController("oneGroup23", "twoGroup2");
	  r4 = new RadioController("oneGroup34", "twoGroup3");
	  r5 = new RadioController("oneGroup45", "twoGroup4");
 и т.д. вбить все значения возможные (максимум около 15-20 переменных)
....

но правильно ли я понял как создавать экземпляры класса?
или это как-то по другому делается?


еще c этим скриптом перестал работать
<label for="1">1111<label><br>

GuardCat 05.04.2012 14:46

nikki4, вообще я зря этот код сделал классом. Лучше вот так:
function uncheckAnother(e) {
  var target, x, radios;
  e = e || window.event;
  target = e.target || e.srcElement;

  if (target.type !== "radio") return false;

  radios = document.querySelectorAll(this.getAttribute("data-classes"));

  for(x = 0; x < radios.length; x++) {
    radios[x].checked = false;
  }
}
function makeRadioFamily() {
  var 
    x, queryString, y,
    fieldsets = document.querySelectorAll("." + Array.prototype.join.call(arguments, ", ."))
  ;

  for(x = 0; x < fieldsets.length; x++) {
    queryString = "";
    for(y = 0; y < arguments.length; y++) {
      if(fieldsets[x].className === arguments[y]) continue;
      if(queryString.indexOf(arguments[y]) != -1) continue;
      queryString += " ." + arguments[y] + " input[type=radio], "
    }
    queryString = queryString.replace(/, $/, "");
    fieldsets[x].setAttribute("data-classes", queryString);
    fieldsets[x].onclick = uncheckAnother;
  }  
}

Использовать так:
makeRadioFamily("oneGroup", "twoGroup");
makeRadioFamily("threeGroup", "fourGroup");
//и т.д.
Пример.

nikki4 05.04.2012 15:34

снова благодарю )
работает как надо, теперь программка почти готова ))

но всеже как-то не хорошо получается, почему label перестали работать? нажимаю на них и не ставятся кружки.. ничего ен происходит, хотя видно есть

GuardCat 05.04.2012 15:49

nikki4, исправлено. Поменяйте в шестой строке (см. мой код в предыдущем посте) false на true и всё заработает.
т.е. вместо
if (target.type !== "radio") return false;

нужно
if (target.type !== "radio") return true;

nikki4 05.04.2012 17:16

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

хотя конечно тут и сам могу справиться- на пхп написать функцию проверки был ли блок с таким именем уже выведен и если да, то изменить имя, но как-то муторно получается.. может как-то проще можно изменив тут в js?

<fieldset class="block1" >
<legend>block1</legend>
<input type="radio" name="1" value="9" id="9"><label for="9">9</label><br>
<input type="radio" name="1" value="10" id="10"><label for="10">10</label><br>
<input type="radio" name="1" value="11" id="11"><label for="11">11</label><br>
</fieldset>

<fieldset class="block2" >
<legend>block1</legend>
<input type="radio" name="1" value="9" id="9"><label for="9">9</label><br>
<input type="radio" name="1" value="10" id="10"><label for="10">10</label><br>
<input type="radio" name="1" value="11" id="11"><label for="11">11</label><br>
</fieldset>
   <script>
    function uncheckAnother(e) {
      var target, x, radios;
      e = e || window.event;
      target = e.target || e.srcElement;
    
      if (target.type !== "radio") return true;
    
      radios = document.querySelectorAll(this.getAttribute("data-classes"));
    
      for(x = 0; x < radios.length; x++) {
        radios[x].checked = true;
      }
    }

    function makeRadioFamily() {
      var
        x, queryString, y,
        fieldsets = document.querySelectorAll("." + Array.prototype.join.call(arguments, ", ."))
      ;
    
      for(x = 0; x < fieldsets.length; x++) {
        queryString = "";
        for(y = 0; y < arguments.length; y++) {
        if(fieldsets[x].className === arguments[y]) continue;
        if(queryString.indexOf(arguments[y]) != -1) continue;
        queryString += " ." + arguments[y] + " input[type=radio], "
        }
        queryString = queryString.replace(/, $/, "");
        fieldsets[x].setAttribute("data-classes", queryString);
        fieldsets[x].onclick = uncheckAnother;
      }  
    }
    </script>

т.е. 2 одинаковых блока, но чтоб значения можно было бы выбрать разные


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