I builded a JQuery component to make a dropdown-accordion element. Each time i click on a item in a accordion, it will save the selection, close this accordion andopen the next one if exists.
To add data, it work as it :
$(window).ready(function () {
$(selector).data('dropdownaccordion').enqueueAccordion({ // Ajax parameter
name: "Commune",
data: {
url: "/trends/list",
method: 'GET',
datatype: "json",
timeout: 5000
}
},
{
name: "Batiment",
data: {
url: "/trends/list/"+this.path[0], // this.path[0] refer to the first selection, as this.path[1] will refer to the second etc
method: 'GET',
datatype: "json",
timeout: 5000
}
},
{ //Note that we can pass array instead of Ajax parameter
name: "Dummy",
data: ["One", "Two", "Three"]
})
});
I designed the component to work good with Rest API.
The problem is exposed for the second element i added. As you can see, i'm trying to pass this.path[0], refering to the first item selected . But the property path doesn't exist in the $(windows).ready scope, but in the $(selector).data('dropdownaccordion') scope.
I can replace it by $(selector).data('dropdownaccordion').path[0]
, but i want something more global, like ExpressJS do in URL ( http://www.dummy.com/path/:item1/:item2 and replacing :itemx by the user selection)
Do you know a better solution, and if not, do you know a way to make it good ?
My Component is designed as follow :
+function ($) {
'use strict';
/**
* Dropdown_Accordion CLASS DEFINITION
*/
function DropdownAccordion(component, ...accordions) {
this.accordions = [];
for(var i=0;i<accordions.length;i++){
this.accordions.push(accordions[i])
}
...
this.component = $(component);
...
// Render the accordions as DOM
this.render.call(this);
//Events
this.component
.on("click", ".accordion-item-body", $.proxy(function(event){
this.path.push($(event.target).text())
this.component.trigger('click.selection.dropdownaccordion', [$(event.target)])
this.openNext(event);
}, this))
.on('show.bs.dropdown', $.proxy(this.showMenu, this))
.on('shown.bs.dropdown', $.proxy(this.openNext, this))
.on('hide.bs.dropdown', $.proxy(function (event) {
this.component.find('.dropdown-menu').first().stop(true, true).slideUp();
this.component.find(".accordion-item .panel-collapse.collapse").each(function(){
$(this).collapse('hide');
});
this.opened = null;
(this.path.length !== this.accordions.length) ? this.component.trigger("abort.selection.dropdownaccordion", [this.path]):null
this.path = []
}, this));
}
DropdownAccordion.prototype = {
constructor: DropdownAccordion,
// Collapse accordion every time dropdown is shown
showMenu: function () {
// show the accordion
},
openNext: function (clickEvent) {
// Open the next accordion
},
render: function () {
// Will render the dropdown-accordion
// The following is how the AJAX request is performed
...
// When the accordion is opened, make the ajax request
DOMaccordion.on("open.accordion.dropdownaccordion", function () {
// The DOM element contains in data the options for the ajax request, or nothing if the accordion is an array
**$.ajax($(this).data('content.accordion.dropdownaccordion'))**
});
...
}
},
enqueueAccordion: function (...accordions) {
for(var i=0; i<accordions.length;i++)
this.accordions.push(accordions[i]);
this.render()
},
dequeueAccordion: function (name) {
this.accordions = this.accordions.filter(function (obj) {
return obj.name !== name;
})
this.render()
}
}
Look at the ** ** in the code, this is where the Ajax options is stored. I want that when i click on a item, there is a substitution on the .url to include the first item clicked.
I hope this seems clearer to you.
You can let enqueueAccordion
accept a callback and pass the current accordion as a parameter:
DropdownAccordion.prototype = {
// ...
enqueueAccordion: function (makeAccordions) {
var accordions = makeAccordions(this);
for (var i = 0; i < accordions.length; i++)
this.accordions.push(accordions[i]);
this.render();
}
}
$(selector).data('dropdownaccordion').enqueueAccordion(function (_this) {
return [
{
name: "Batiment",
data: {
url: "/trends/list/" + _this.path[0],
method: 'GET',
datatype: "json",
timeout: 5000
}
];
});
If you want to use this
directly, you can temporarily attach the callback to the current accordion:
DropdownAccordion.prototype = {
// ...
enqueueAccordion: function (makeAccordions) {
this.makeAccordions = makeAccordions;
var accordions = this.makeAccordions();
delete this.makeAccordions;
for (var i = 0; i < accordions.length; i++)
this.accordions.push(accordions[i]);
this.render();
}
}
$(selector).data('dropdownaccordion').enqueueAccordion(function () {
return [ // Ajax parameters
{
name: "Batiment",
data: {
url: "/trends/list/" + this.path[0],
method: 'GET',
datatype: "json",
timeout: 5000
}
}
];
});
I dug through the expressjs code, and found how they do the URL substituion. It work with the path-to-regex module. It seems not to be developped for browserside so i had to found another solution.
@aaron inspired me, and i finally add the possibility to have a callback in place of the url :
{
name: "Capteur",
data: {
url: function (path) {
return "/trends/list/" + path[0] + "/" + path[1]
},
method: 'GET',
datatype: "json",
timeout: 5000
}
}
By doing this, people are now able to modify the path based on the previous selection.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.