Home > Net >  How to use a JQuery function twice in the same page?
How to use a JQuery function twice in the same page?

Time:04-06

I'm not really great at coding, but I eventually do some stuff for my office.

I'm currently building an accordion that carries some information from a json. I use a JQuery code I got in the internet to build it.

Problem is I'm trying to call this JQuery function twice in the same HTML page, building two different accordion sets with two different json data.

I've tried changing the JQuery, calling one "accordion.init()" and another "accordion2.init(), with several different variations, but didn't succeed.

My html is pretty straight foward:

<script src="fase2.js"></script>
<div >
<section ></section> 
</div>

And the js file that the HTML inherits:

jQuery(document).ready(function($){
    var accordion={
        init:function(){
            this.accordionJson='fase2.json';
            this.getData();
        },
        getData:function(){
            $.ajax({
                url:accordion.accordionJson,
                success:function(data){
                    var dataBlock=data.data;
                    accordion.iterateAccordionData(dataBlock);
                    accordion.hideAccordion();
                }
            });
        },
        iterateAccordionData:function(accordionData){
            for(i=0;i<accordionData.length;i  ){
                $(".accordion").append("<article>");
            }
            accordion.appendAccordionContent(accordionData);
        },
        appendAccordionContent:function(accordionData){
            $('article').each(function(index){
                $('article').eq(index).append('<h2><img src= "'   accordionData[index]['Logo']  '">'   accordionData[index]['FriendlyName']   '<span> #'   accordionData[index]['index']   '</span></h2>');
                $('article').eq(index).append('<p><span>Role</span>:<br>'   accordionData[index]['Roles']  '</p>')
                $('article').eq(index).append('<p><span>APIs:</span><br>' accordionData[index]['ApiFamilyType'] '</p>');
                $('article').eq(index).append('<p><span>Endpoints:</span><br>' accordionData[index]['ApiEndpoints'] '</p>');
                $('article').eq(index).append('<p><span>Organisation:</span><br>' accordionData[index]['OrganisationName'] '</p>');
            });
        },
        hideAccordion:function(){
            $('p').hide();
            accordion.toggleAccordion();
        },
        toggleAccordion:function(){
            $('article').on('click',function(){
                $(this).find('p').slideToggle();
                $(this).toggleClass('active');
            });
        },
    };
    accordion.init();
});

What I have tried to do is calling a second js file, with different names to most of the variables:

jQuery(document).ready(function($){
var accordion2={
    init:function(){
        this.accordionJson='fase2-n.json';
        this.getData();
    },
    getData:function(){
        $.ajax({
            url:accordion2.accordion2Json,
            success:function(data){
                var dataBlock=data.data;
                accordion2.iterateAccordionData(dataBlock);
                accordion2.hideAccordion();
            }
        });
    },
    iterateAccordionData:function(accordionData2){
        for(i=0;i<accordionData2.length;i  ){
            $(".accordion").append("<article>");
        }
        accordion2.appendAccordionContent(accordionData2);
    },
    appendAccordionContent:function(accordionData2){
        $('article').each(function(index){
            $('article').eq(index).append('<h2><img src= "'   accordionData2[index]['Logo']  '">'   accordionData2[index]['CustomerFriendlyName']   '<span> #'   accordionData2[index]['index']   '</span></h2>');
            $('article').eq(index).append('<p><span>Role ITP</span>:<br>'   accordionData2[index]['Roles']  '</p>')
            $('article').eq(index).append('<p><span>Família de APIs publicadas:</span><br>' accordionData2[index]['ApiFamilyType'] '</p>');
            $('article').eq(index).append('<p><span>Endpoints publicados:</span><br>' accordionData2[index]['ApiEndpoints'] '</p>');
            $('article').eq(index).append('<p><span>Organizações que utilizam está marca:</span><br>' accordionData2[index]['OrganisationName'] '</p>');
        });
    },
    hideAccordion:function(){
        $('p').hide();
        accordion2.toggleAccordion();
    },
    toggleAccordion:function(){
        $('article').on('click',function(){
            $(this).find('p').slideToggle();
            $(this).toggleClass('active');
        });
    },
};
accordion2.init();
});

But I end up with an error:

Uncaught TypeError: Cannot read properties of undefined (reading 'Logo') at HTMLElement. (fase2-n.js:25:88)

which is this line:

$('article').eq(index).append('<h2>imgsrc="' accordionData2[index]'Logo'] '">' accordionData2[index]['CustomerFriendlyName'] '<span>#' accordionData2[index]['index'] '</span></h2>');

This error is making me confused, because if I print something like: console.log(accordionData2[0]['Logo'], the js code will give me a positive result for a logo in my json.

Could you help me understand what is incorrect?

obs: the accordion loads properly with only one jQuery being called. obs2: With the code I posted here, the data from the second json loads together with the first accordion, one accordion on top of another. I imagine the error above only presents itself after the first json data ends (the first json index is smaller than the second)

CodePudding user response:

I would do:

    jQuery(document).ready(function($){
    var accordion={
        init:function(jsonFile){
            this.accordionJson= jsonFile ;
            this.getData();
        },
        getData:function(){
            $.ajax({
                url:accordion.accordionJson,
                success:function(data){
                    var dataBlock=data.data;
                    accordion.iterateAccordionData(dataBlock);
                    accordion.hideAccordion();
                }
            });
        },
        iterateAccordionData:function(accordionData){
            for(i=0;i<accordionData.length;i  ){
                $(".accordion").append("<article>");
            }
            accordion.appendAccordionContent(accordionData);
        },
        appendAccordionContent:function(accordionData){
            $('article').each(function(index){
                $('article').eq(index).append('<h2><img src= "'   accordionData[index]['Logo']  '">'   accordionData[index]['FriendlyName']   '<span> #'   accordionData[index]['index']   '</span></h2>');
                $('article').eq(index).append('<p><span>Role</span>:<br>'   accordionData[index]['Roles']  '</p>')
                $('article').eq(index).append('<p><span>APIs:</span><br>' accordionData[index]['ApiFamilyType'] '</p>');
                $('article').eq(index).append('<p><span>Endpoints:</span><br>' accordionData[index]['ApiEndpoints'] '</p>');
                $('article').eq(index).append('<p><span>Organisation:</span><br>' accordionData[index]['OrganisationName'] '</p>');
            });
        },
        hideAccordion:function(){
            $('p').hide();
            accordion.toggleAccordion();
        },
        toggleAccordion:function(){
            $('article').on('click',function(){
                $(this).find('p').slideToggle();
                $(this).toggleClass('active');
            });
        },
    };
    accordion.init('fase2.json');
    accordion.init('fase3.json');
});

And then you can have one single function, sending the filename in the init() props. If you need more than one accordion working at the same time, you should replace $("article") to something like $(this).find("article") so the selector will touch only the closest element of the iniciator and not all of them

  • Related