locked
Reference element in previous find RRS feed

  • Question

  • User-1826049516 posted

    Hi,

    <div>
    	<img class="" data-view="true" src="xyz" alt="xyz" />
    	<img class="hidden" data-view="false" src="789" alt="789" />
    </div>
    $( "div" ).find( "img" ).toggleClass( "hidden", true | false );

    Is it possible to reference $( this ) in the toggleClass action, with $( this ) being the element matched from the find, directly in chaining rather than calling a function from toggleClass?

    $( "div" ).find( "img" ).toggleClass( "hidden", $( this ).data( "view" ) );

    Basically, when pressing one button ('Edit') it toggles these 2 images class. If they press another button ('Cancel') I want the states of the images class to return to the page load state, using a data-attribute as the 'page load default'. I can't just do a simple toggle / toggleClass because just pressing cancel will toggle them, not return them to the default state.

    Thanks

    Wednesday, June 12, 2019 10:05 AM

All replies

  • User475983607 posted

    I don't think you are using the toggleClass() correctly.

    http://api.jquery.com/toggleclass/

    The toogleClass() function adds or removes a class depending if the class exists or not.   In your example the class hidden is either present or not.

    To go back to the original state, other than hidden, requires that you write code to save the state of the original style.  That's usually a variable.  Unfortunately, there is no indication what the original state was...

    Wednesday, June 12, 2019 10:31 AM
  • User-1826049516 posted

    Yes, that is the default action if only the class parameter is specified.

    But toggleClass can accept 2 parameters; which class to toggle and boolean to indicate whether the class should be added or removed.

    In this case, the original state is stored in the data-view property. When pressing certain buttons the class should be either added or removed based on the data-view value (which is true or false)

    If I manually specify true or false, the correct action happens:

    $( "div" ).find( "img" ).toggleClass( "hidden", true ); <-- adds class, even it is already set
    $( "div" ).find( "img" ).toggleClass( "hidden", false ); <-- removes class, even it isn't already set

    I need to grab the value from data-view from the image.

    Wednesday, June 12, 2019 12:48 PM
  • User475983607 posted

    ldoodle

    toggleClass can accept 2 parameters; which class to toggle and boolean to indicate whether the class should be added or removed.

    In this case, the original state is stored in the data-view property. When pressing certain buttons the class should be either added or removed based on the data-view value (which is true or false)

    I still do not fully understand what original mean in this context.  But it seems you want to toggle "hidden" in which case the second argument is not needed as explained in the documentation.

    http://api.jquery.com/toggleclass/

    This method takes one or more class names as its parameter. In the first version, if an element in the matched set of elements already has the class, then it is removed; if an element does not have the class, then it is added. For example, we can apply .toggleClass() to a simple <div>:

    <div class="syntaxhighlighter xml">
    <div class="line n1">1</div> <div class="container"> <div class="line"><div class="tumble">Some text.</div></div> </div>
    </div>

    The first time we apply $( "div.tumble" ).toggleClass( "bounce" ), we get the following:

    <div class="syntaxhighlighter xml">
    <div class="line n1">1</div> <div class="container"> <div class="line"><div class="tumble bounce">Some text.</div></div> </div>
    </div>

    The second time we apply $( "div.tumble" ).toggleClass( "bounce" ), the <div> class is returned to the single tumble value:

    <div class="syntaxhighlighter xml">
    <div class="line n1">1</div> <div class="container"> <div class="line"><div class="tumble">Some text.</div></div> </div>
    </div>

    Applying .toggleClass( "bounce spin" ) to the same <div> alternates between <div class="tumble bounce spin">and <div class="tumble">.

    As I understand your requirement, all you have to do is initial the element (original) then invoke toggleClass().  If "hidden" exists it will be removed.  If hidden does not exit, it is added.

    If the "original" class is somehting other than "hidden" then you need to write some code.

    Wednesday, June 12, 2019 12:57 PM
  • User475983607 posted

    ldoodle

    Yes, that is the default action if only the class parameter is specified.

    But toggleClass can accept 2 parameters; which class to toggle and boolean to indicate whether the class should be added or removed.

    In this case, the original state is stored in the data-view property. When pressing certain buttons the class should be either added or removed based on the data-view value (which is true or false)

    If I manually specify true or false, the correct action happens:

    $( "div" ).find( "img" ).toggleClass( "hidden", true ); <-- adds class, even it is already set
    $( "div" ).find( "img" ).toggleClass( "hidden", false ); <-- removes class, even it isn't already set

    I need to grab the value from data-view from the image.

    That's not exactly how toggleClass() works according to the documentation.

    A Boolean (not just truthy/falsy) value to determine whether the class should be added or removed.

    Pass the second argument to add or remove the class.  The way the current code is written, you'll get the same results simply removing the second argument.  Otherwise, you need to toogle the data-view or store the state of data-view.

    }<div>
        <img src="~/Content/images/minus.png" />
        <img class="hidden" src="~/Content/images/plus.png" />
    </div>
     <div>
         <input id="Button1" type="button" value="Toggle" />
     </div>
        <script>
            $('#Button1').click(function () {
                $('img').toggleClass('hidden');
            });
        </script>

    Wednesday, June 12, 2019 1:10 PM
  • User-1826049516 posted

    Ok. So on page load (aka 'original state'):

    <div>
    	<img class="" data-view="true" src="xyz" alt="xyz" /> <-- visible on page load
    	<img class="hidden" data-view="false" src="789" alt="789" /> <-- hidden on page load
    </div>

    User presses 'Edit' button which changes them to this:

    <div>
    	<img class="hidden" data-view="true" src="xyz" alt="xyz" /> <-- now hidden
    	<img class="" data-view="false" src="789" alt="789" /> <-- now visible
    </div>

    They then click the now visible image (which changes src between an unchecked and checked box):

    <div>
    	<img class="hidden" data-view="true" src="xyz" alt="xyz" />
    	<img class="" data-view="false" src="123" alt="123" />
    </div>

    User then presses 'Cancel' button so they should revert back, both class and src:

    <div>
    	<img class="" data-view="true" src="xyz" alt="xyz" /> <-- visible again
    	<img class="hidden" data-view="false" src="789" alt="789" /> <-- hidden again
    </div>

    I cannot simply use toggleClass( "hidden" ) because if somebody pressed Edit > Cancel (change src to 123) > Edit > Cancel (change src back to 789) > Edit > Cancel (change src to 123) that would cause a simple toggle each time which is not what I want. When Cancel is pressed it must always revert each image to its page load state, as set in the data-view property which never changes.

    Hence:

    $( "div" ).find( "img" ).toggleClass( "hidden", $( this ).data( "view" ) );

    Which should result in:

    $( "div" ).find( "img" ).toggleClass( "hidden", true | false ); <-- true | false based on value in data-view

    But this doesn't work, presumably because $( this ) is not actually the image element so data-view property is not found.

    Wednesday, June 12, 2019 1:21 PM
  • User-1826049516 posted

    This it what works, but I was just interested to see if you could use $( this ) directly inside an action to get the element from the previous action, i.e. .find( "img" ) = $( this ) in toggleClass

    $( "div" ).find( "img" ).each( function() {
    
    	$( this ).toggleClass( "hidden", $( this ).data( "view" ) );
    
    } );

    Wednesday, June 12, 2019 1:35 PM
  • User475983607 posted

    This it what works, but I was just interested to see if you could use $( this ) directly inside an action to get the element from the previous action, i.e. .find( "img" ) = $( this ) in toggleClass

    No, that's no how "this" works.  It is up to you build code that manages application state.  Code like below saves the state of the class attribute when the page loads.  The cancle button sets the state to the original.

    <div>
        <img src="~/Content/images/minus.png" />
        <img class="hidden" src="~/Content/images/plus.png" />
    </div>
     <div>
         <input id="Edit" type="button" value="Edit" />
     </div>
     <div>
         <input id="Cancel" type="button" value="Cancel" />
     </div>
        <script>
            //Remember the original state when the page loads
            $('img').each(function () {
                if ($(this).attr('class') == null) {
                    $(this).data('originalClassState', 'defaultClass');
                } else {
                    $(this).data('originalClassState', $(this).attr('class'));
                }
            });
    
            //toggle
            $('#Edit').click(function () {
                $('img').toggleClass('hidden');
            });
    
            //Cancel
            $('#Cancel').click(function () {
                $('img').each(function (index, value) {
                    $(this).attr('class', $(this).data('originalClassState'));
                });
            });
    
        </script>

    Wednesday, June 12, 2019 1:58 PM
  • User-474980206 posted

    you have a couple options.

    use each to access this for each match:

    $("div img").each(function() {
       $(this).toggleClass("hidden", $(this).data("view") == "false"); 
    });

    use two selectors:

    $("div img[data-view=false]").toggleClass("hidden",true); 
    $("div img[data-view=true]").toggleClass("hidden",false); 
    

    Wednesday, June 12, 2019 4:28 PM