3

I am very new to Angular and I would like to get some help, I have a pure JavaScript code for an accordion that I want to convert into an Angular Directive, I read the Angular Documentation and everything but I don't know where to start.

this is the simple HTML that I have so far:

     <div id="divMiAccordion2" class="panel-group">
        <div class="panel panel-default">
            <div class="panel-heading">
              <h3  class="panel-title">Sección 1</h3>
            </div>
            <div class="panel-body">
                <p>
                    Texto sección 1
                </p>
            </div>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">
              <h3  class="panel-title">Sección 2</h3>
            </div>
            <div class="panel-body">
                <p>
                    Texto sección 2
                </p>
            </div>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">
              <h3  class="panel-title">Sección 3</h3>
            </div>
            <div class="panel-body">
                <p>
                    Texto sección 3
                </p>
            </div>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">
              <h3  class="panel-title">Sección 4</h3>
            </div>
            <div class="panel-body">
                <p>
                    Texto sección 4
                </p>
            </div>
        </div>
    </div>

and this is my JavaScript:

function Accordion(opciones){

var opts = {
    divId:'divMiAccordion',
    displayMode: 'single',
    titleEvent: 'mouseover',
    headerClassName: 'custColor',
    contentClassName: 'custContent',
    centerTitle: false,
    centerContent: false
    };

var acc1 = new Accordion(opts);


var acc2 = new Accordion({
    divId:'divMiAccordion2',
    displayMode: 'multiple',
    titleEvent: 'click'
});

var self = this;
this.init = function(){

    this.container = document.getElementById(opciones.divId);
    this.contenedores = this.container.querySelectorAll('div.panel-body');
    this.titulos = this.container.querySelectorAll('h3');
    this.options = opciones;

    for(var i=0; i<this.contenedores.length; i++){

        this.contenedores[i].classList.add('hidden');
    }

    for (var i = 0; i < this.titulos.length; i++) {
        if(this.options.titleEvent === 'click'){
            this.titulos[i].onclick = tituloEvent;
        }
        else{
            this.titulos[i].onmouseover = tituloEvent;
        }
    };
} //fin init

this.getId = function(){
    return self.container.id;
}

function tituloEvent(){

    var tempNode = null;

    if(self.options.displayMode === 'single'){

        for (var i = 0; i < self.titulos.length; i++) {
            tempNode = self.titulos[i].parentNode.nextElementSibling;
            tempNode.classList.add('hidden');                   
        };          
    }

    tempNode = this.parentNode.nextElementSibling;
    if(tempNode.classList.contains('shown')){
        tempNode.classList.add('hidden');           
        tempNode.classList.remove('shown');         
    }
    else{   
        tempNode.classList.add('shown');            
        tempNode.classList.remove('hidden');            
    }       
}

function headerClass () {
    var header = document.getElementsByClassName('header').onclick = headerClass();
    clas = document.getElementsByClassName('class').onclick = classClass(),
    panel = document.getElementsByClassName('panel-title');

    if (header.clicked) {
        panel.className = 'color: blue';
    };
}

function classClass () {

}

this.init();

} //fin accordion
3
  • 1
    Instead of making a directive, unless you want to make one for fun, I would use the Angular-UI directive for Bootstrap, which already has the accordion feature you're looking for. Just look at the docs for ui.bootstrap.accordion. Commented Dec 23, 2014 at 20:26
  • @A.Alger yes I know I can use it, but I am using Angular-Strap, and tried to add Angular-UI but it gives an error, a conflict with classes I guess. Commented Dec 23, 2014 at 20:28
  • 1
    I suggest switching then to Angular-UI since the accordion is already in it. If you're having trouble, just switch out the elements and the JS, which is what you need to do to get it working. Commented Dec 23, 2014 at 20:35

1 Answer 1

1

Here is a sample directive that can help you pull apart your code and find where to place it.

/**
 * Sample Directive
 */

define(['sampleLink', 'sampleCtrl'], function (link, controller) {
function sampleDir () {
    return {
        /**
         * require is used by the link option
         * can be a single controller, or an array. '^myController', or ['^controller2', '^controller1']
         * controllers to be used in the link section. link (scope, element, attrs, requires)
         *
         * '^myController' - use ^ to search up the parents for the controller, otherwise it only looks at it's own element and will throw an error
         * */
        require : '',

        /* restrict what type of elements this directive is rendered on E=element <directive> or A=attribute <element data-directive> */
        restrict : 'EA',

        /* *
         * transclude in or outer scope. true = use the outer scope that this directive belongs to. false = create a scope inside the directive
         *      only use true when you want to create a directive that wraps arbitrary content
         *      when you use false and create a scope, you will want to pass in scope, or data through attributes on the element
         * */
        transclude : false,

        /* *
         * scope = create an isolate scope for the directive pass data into the directive through attributes
         *      This allows us to isolate the scope and reuse these directives throughout an app.
         *      =attr means to bind data to that attribute
         *      &attr means with transclude turned on this attribute will trigger evaluation of an expression in the context of the original scope
         *          any expression is allowed, including a function, this is ideal for binding callback functions to directive behaviors
         *          use this when we want the directive to expose an API for binding behaviors
         * */
        scope : {
            inputObject : '=inputObject',
            /*'close' : '&onClose'*/
        },

        /* templateUrl = Point to the template this directive should render */
        templateUrl : '/a/tpl/modules/util/input/inputs.html',

        /**
         * link : use link when you want to manipulate the dom with the directive
         * takes a function, inline or it can be dependency injected through requireJS
         * use the following signature function lin k(scope, element, attrs) { ... }
         *
         * scope is an angular scope object
         * element is the jqLite wrapped element that this directive matches
         * attrs is a hash object with key-value pairs of normalized attribute names and their values
         * */
        link : link,

        /**
         * Specify a controller, and use controllerAs to alias the scope, if you want to reference the scope or it's functions in the template.
         * You must define scope in the directive for this to be used.
         *
         * Q: What's the difference between controller and link? - A: Controllers can expose an API, and link can interact with controllers using require
         *
         * Best Practice: Only use controller when you want to expose the directive controller to another directive. Otherwise use Link
         *
         * This is great for building complicated directives that are made up of other directives and need to communicate with one another.
         * */
        controller : controller
        /*controllerAs : 'input'*/

    }
}

return sampleDir;
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.