admin管理员组

文章数量:1394544

Description

So I have a form that has a button that when clicked I would like to toggle the readonly attribute of all child elements of a fieldset.

The HTML:

<form>
    <fieldset id="F1">
        <textarea id="T1" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T2" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T3" rows="5" cols="50" readonly required></textarea><br>
    </fieldset>
    <button type="button" id="button" onclick="togglerequire('#F1')">
        Click Me
        </button>
</form>

The jquery:

function togglerequire(id){
    $(id).children().each(function(){
        var re = $(this).prop('required');
        $(this).prop('required', !re);
    });
}

Back to the Question:

I can get this to work for individual elements by id but as soon as I attempt to perform the toggle on child elements defined by the parent id, it stops working and I can't figure out why.

Description

So I have a form that has a button that when clicked I would like to toggle the readonly attribute of all child elements of a fieldset.

The HTML:

<form>
    <fieldset id="F1">
        <textarea id="T1" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T2" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T3" rows="5" cols="50" readonly required></textarea><br>
    </fieldset>
    <button type="button" id="button" onclick="togglerequire('#F1')">
        Click Me
        </button>
</form>

The jquery:

function togglerequire(id){
    $(id).children().each(function(){
        var re = $(this).prop('required');
        $(this).prop('required', !re);
    });
}

Back to the Question:

I can get this to work for individual elements by id but as soon as I attempt to perform the toggle on child elements defined by the parent id, it stops working and I can't figure out why.

Share Improve this question asked Mar 3, 2017 at 13:58 Petay87Petay87 1,7735 gold badges25 silver badges39 bronze badges 3
  • You want to toggle the readonly property as well as the required property, or instead of? – David Thomas Commented Mar 3, 2017 at 14:09
  • as well as but if I can figure out how to do one I assumed I would be able to do it for both. – Petay87 Commented Mar 3, 2017 at 14:13
  • You can, but there's absolutely no need when there's a far simpler alternative; my answer, below, might be easier to use. – David Thomas Commented Mar 3, 2017 at 14:41
Add a ment  | 

5 Answers 5

Reset to default 2

You need to update the function to following

function togglerequire(id){
    $(id).children("textarea").each(function(){
        var re = $(this).prop('readonly'); 
        $(this).prop('readonly', !re);
    });
}

Please note you were toggling the wrong property. Additionally, it is better we can provide the specific selector like textarea or class etc.

As you are using jquery so you can find an element and get all its children having readonly and then call .toggle like the following snippet:-

$('#button').click(function(){
   $('#F1').children('[readonly]').toggle();
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset id="F1">
    <textarea id="T1" rows="5" cols="50" readonly required></textarea><br>
    <textarea id="T2" rows="5" cols="50" readonly required></textarea><br>
    <textarea id="T3" rows="5" cols="50" readonly required></textarea><br>
</fieldset>
<button type="button" id="button">Click Me</button>

And same is the case for required or both readonly and required like:

$('#F1').children('[required]').toggle();// Correct
$('#F1').children('[readonly]').toggle();// Correct
$('#F1').children('[readonly][required]').toggle();// Correct

$('#F1').children('readonly').toggle();// incorrect

Note: If you will try to get Childerns without [] for readonly like $('#F1').children('readonly').toggle(); this will not toggle. You need to put [] around readonly or required or both.

Update 1

As you wanted to make them readonly. Here is the snippet which will make all child elements having required attribute, readonly at click event.

$('#button').click(function(){
   $('#F1').children('[required]').prop('readonly', true);
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset id="F1">
    <textarea id="T1" rows="5" cols="50"  required></textarea><br>
    <textarea id="T2" rows="5" cols="50"  required></textarea><br>
    <textarea id="T3" rows="5" cols="50"  required></textarea><br>
</fieldset>
<button type="button" id="button">Click Me</button>

While you've already accepted an answer, I'd suggest that if the intent is to prevent user-interaction with the <textarea> elements in the :disabled/readonly state, then it's easier to avoid iterating over those children, and instead assign the disabled property to the parent <fieldset>:

// named function to call:
function toggleActiveStatus() {

  // I'm using native DOM approaches here simply because
  // they're 'cheaper' (premature optimisation, however)
  // than invoking jQuery unnecessarily.

  // here we use let statement to assign the element found
  // by 'document.querySelector()' (which returns the first
  // element matching the supplied CSS selector, or null if
  // there is no matching element) to the 'parent' variable:
  let parent = document.querySelector(

    // here we retrieve the CSS selector held in the
    // <button> element's 'data-affects' custom
    // (and valid) data-* attribute:
    this.dataset.affects
  ),

    // here we find the current state of the
    // element, returned as a Boolean true
    // if the <fieldset> is disabled or
    // false if the <fieldset> is not
    // disabled:
    currentState = parent.disabled;

  // here we simply set the disabled property
  // of the <fieldset> to the inverse of its
  // current state:
  parent.disabled = !currentState;

}

// binding the named function (note the deliberate
// lack of parentheses) using jQuery, rather than
// in-line event-handlers, to avoid the use of
// difficult-to-maintain JavaScript, and switching
// to the 'unobtrusive' JavaScript approach:
$('#button').on('click', toggleActiveStatus);

function toggleActiveStatus() {
  let parent = document.querySelector(this.dataset.affects),
    currentState = parent.disabled;

  parent.disabled = !currentState;

}

$('#button').on('click', toggleActiveStatus);
body {
  margin-bottom: 5em;
}

textarea {
  display: block;
}

button {
  text-transform: sentence;
}

#F1:disabled+button::before {
  content: "enable";
}

#F1:not(:disabled)+button::before {
  content: "disable";
}

#F1+button::after {
  content: ' textarea elements';
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <fieldset id="F1">
    <textarea id="T1" rows="5" cols="50" readonly required></textarea>
    <textarea id="T2" rows="5" cols="50" readonly required></textarea>
    <textarea id="T3" rows="5" cols="50" readonly required></textarea>
  </fieldset>
  <button type="button" id="button" data-affects="#F1"></button>
</form>

Also, as jQuery is in no way necessary for this approach, the following shows a pure JavaScript approach, using the native DOM API:

function toggleActiveStatus() {
  let parent = document.querySelector(this.dataset.affects),
    currentState = parent.disabled;

  parent.disabled = !currentState;

}

// here we use document.querySelector(), as above, to find
// the first element matching the supplied CSS selector:
document.querySelector('#button')

  // and then use EventTarget.addEventListener() to bind
  // the named function (again: note the deliberate lack
  // of parentheses) as the event-handler for the 'click'
  // event:
  .addEventListener('click', toggleActiveStatus);

function toggleActiveStatus() {
  let parent = document.querySelector(this.dataset.affects),
    currentState = parent.disabled;

  parent.disabled = !currentState;

}

document.querySelector('#button').addEventListener('click', toggleActiveStatus);
body {
  margin-bottom: 5em;
}

textarea {
  display: block;
}

button {
  text-transform: sentence;
}

#F1:disabled+button::before {
  content: "enable";
}

#F1:not(:disabled)+button::before {
  content: "disable";
}

#F1+button::after {
  content: ' textarea elements';
}
<form>
  <fieldset id="F1">
    <textarea id="T1" rows="5" cols="50" readonly required></textarea>
    <textarea id="T2" rows="5" cols="50" readonly required></textarea>
    <textarea id="T3" rows="5" cols="50" readonly required></textarea>
  </fieldset>
  <button type="button" id="button" data-affects="#F1"></button>
</form>

References:

  • HTML:
    • Custom data-* attributes.
  • JavaScript:
    • document.querySelector().
    • EventTarget.addEventListener().
    • HTMLFieldsetElement.
    • let statement.
    • Logical NOT (!) operator.
  • jQuery:
    • on().

Try this:

function toggleAttributesOn(selector, elementSelector, attribute) {
   var container = document.querySelector(selector);
   if(!!container && !!attribute) {
     var elements = [].slice.call(container.querySelectorAll(elementSelector));
     elements.forEach(function(element) {
       if(['readonly', 'required'].indexOf(attribute) > -1) {
         element.getAttribute(attribute) !== null? element.removeAttribute(attribute): element.setAttribute(attribute, true); 
       }
       else {
         element.setAttribute(attribute, !element.getAttribute(attribute));
       }
     });
   }
}



// demo code
function togglerequire(selector) {
   toggleAttributesOn(selector, 'textarea', 'readonly');
}
<form>
    <fieldset id="F1">
        <textarea id="T1" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T2" rows="5" cols="50" readonly required></textarea><br>
        <textarea id="T3" rows="5" cols="50" readonly required></textarea><br>
    </fieldset>
    <button type="button" id="button" onclick="togglerequire('#F1')">
        Click Me
        </button>
</form>

This should do the trick. Grabs all inputs within this div and marks them as disabled.

$("#divID:input").attr("disabled", true);

本文标签: javascriptHow do I toggle the readonly attribute of all child element with jqueryStack Overflow