Keep Jquery accordion menu open on current page - javascript

I am sure that i will get help in my particular case. No doubt there are many solutions to achieve this but in my case I am unable to achieve it.
Following is my code to generate html dynamically using java script.
Edit 1: I just want to keep open the current pan of accordion as per href attribute of anchor tag which is in fact current page URL. This is it.
JS code to generate html:
<script>
$.ajax({
url: "/categories",
type: 'GET',
success: function(data) {
var content = "";
content += '<div id="category-navigation">';
for (i = 0; i < data.length; i++) {
content += '<div class="head">';
content += '<label class="categoryLables">' + data[i].title;
content += '</label>';
content += '<div>';
content += '<div class="boardsMargin">';
content += '<ul>';
for (j = 0; j < data[i].assigned_boards.length; j++) {
content += '<li>';
content += "<a href='/#categories/" + data[i].id + "/boards/" + data[i].assigned_boards[j].id + "'>";
content += data[i].assigned_boards[j].name;
content += '</a>';
content += '</li>';
}
content += '</ul>';
content += '</div>';
content += '</div>';
content += '</div>';
}
content += '</div>';
$("#myNavigation").html("");
$("#myNavigation").html(content);
$('.head').accordion({
heightStyle: "content",
active: true,
collapsible: true
});
}
});
</script>
HTML:
<div class="myNavigation">
</div>
Edit 2: For more clear view, this is picture of my accordion.
As a side note: I am working in ruby 2.2.1 and rails 4.1

You can use localStorage like so:
$(function () {
$("#accordion").accordion();
if (localStorage.getItem('active') != null) {
$($('h3').get(parseInt(localStorage.getItem('active')))).trigger("click");
}
});
$('h3').click(function () {
localStorage.setItem('active', $(this).index("h3"));
});
Here is the JSFiddle demo :)
Note: You may also want to read about sessionStorage

Try setting active option in accordion to the index of panels you want to keep open i.e 0,1,2 etc and set collapsible to false
As per the docs:
Integer: The zero-based index of the panel that is active (open). A negative value selects panels going backward from the last panel.
Reference: http://api.jqueryui.com/accordion/#option-active
JS:
$('.head').accordion({
heightStyle: "content",
active: 1, //Change this
collapsible: false
});

Related

Add checkbox from JavaScript

I have an HTML page that contains only an empty <div id="data"></div> and in javascript, I got the information from the database through the ajax and return it back to javascript then print it out in the <div id="data"></div>
I've set the data to be in the columns, now if I want to add another column and this column would contain a button if I click on it then the row will be deleted. (I know how to do the delete through ajax and return it back, etc..) but the question is how could I do the button?
If I add it inside the div = data it will be printed once, and if I add it inside the javascript file then I won't able to add a click listener .. how could I do that?
let printItems = document.getElementById("data");
function succes(user) {
let info = "<div class='infoTable'>";
for (let i = 0; i < user.length; i++) {
info += "<div class='info'>";
info += "<div class='fcol'>" + (i+1) + "</div>";
info += "<div class='scol'>" + user[i].name + "</div>";
info += "<div class='tcol'>" + user[i].quantity + "</div>";
info += "I NEED TO ADD THE BUTTON HERE TO HAVE user[i].ID";
info += "</div>";
}
info += "</div>";
printinfo.innerHTML = info;
}
<div id="data"></div>
Okay, you did the hard part. What you are looking is very easy and you can do that in more than one way. I can suggest you an easier way to me. Write a function which delete the row (from UI and ajax). Now your problem is how to call that function for each row. So you can attach a onclick function for every row you created.
For example:
info += '<button onclick="deleteRowFunction"> Delete This<button />';
Now every time you click the button your delete function called. But how to determine which function is called?
That can be solved by following ways:
info += '<button onclick="deleteRowFunction(\'' + user[i].ID + '\')"> Delete This<button />';
The other easy way is to use data- attribute:
For example:
info += '<button data-userId=' + user[i].ID + ' onclick="deleteRowFunction"> Delete This<button />';
In this way you can get the ID in the deleteRowFunction. You can read all the details here
const user = [{
name: "ABC",
quantity: 2,
}, {
name: "XYZ",
quantity: 1,
}, {
name: "abcdef",
quantity: 12,
}];
let printItems = document.getElementById("data");
function deleteButton(e){
const targetButton = e.target;
targetButton.parentElement.parentElement.remove();
}
function succes(user) {
let info = "<div class='infoTable'>";
for (let i = 0; i < user.length; i++) {
info += `<div class='info'>
<div class='fcol'>${(i + 1)}</div>
<div class='scol'>${user[i].name}</div>
<div class='tcol'>${user[i].quantity}</div>
<div class='tcol'><button onclick="deleteButton(event)">Delete</div>
</div>`;
}
info += "</div>";
printItems.innerHTML = info;
}
succes(user);
<div id="data"></div>

slideToggle() doesn't push elements created with jquery append() down

I do have a problem using slideToggle(). The following DOM elements won't be pushed down, they just overlap. I tried a lot of versions. I do create the tags with jquery getting a JSON from which I fill in the tag content, so I iterate over the JSON to create the HTML tags for each element :
var project_infos = '';
jQuery(document).ready(function(){
$.getJSON('project.json', function(data){
project_infos += '<div class=\"row\">'
+ '<div class=\"span3\">'
+ '<div class=\"well\">'
+ '<div>'
+'<ul class=\"nav nav-list sidebar-list\">';
for( var i = 0; i < data.length; i ++ ) {
var project_name = data[i]["item"];
project_infos += '<li>'
+'<label class=\"tree-toggler nav-header\">'
+'<i class=\"fa fa-arrow-right\"></i>' + project_name + '</label>'
+'<ul class=\"nav nav-list tree\">'
+'<li><label class=\"tree-toggler nav-header\">Katalogue</label></li>'
+'<li>'
+'<ul class=\"nav nav-list tree\">'
+'<li>Link</li>'
+'<li>Link</li>'
+'<li>Link</li>'
+'</ul>'
+'</li>'
+'<li><label class=\"tree-toggler nav-header\">History</label></li>'
+'<li><label class=\"tree-toggler nav-header\">Whole project</label></li>'
+'</ul>'
+'</li>';
}
project_infos += '</ul></div></div></div></div>';
$('#tree').append(project_infos);
$('.tree-toggler').click(function () {
$(this).parent().children('ul.tree').slideToggle('slow');
});
});
});
EDIT : screenshot of html output.
screenshot html output
Thanks in advance!
Use
find() instead of children()
$(this).parent().find('ul.tree').slideToggle('slow');
children() will only search for first level child elements.
I just reset all css styles for my div and finally it worked. I already defined styles for the sidebar and for the ul and li tags. One of the styles was the problem. It kept the elements from toggle down in the sidebar.
Thanks for your time!

Search cloned select object for option value and set selected if exists

What I'm trying to do is clone a template select dropdown element, alter it's attributes some, and then look to see if a string exists as an option value and if it does then go ahead and preselect that option value before I append it.
/* Generated HTML inputs for mapping */
function build_map_input( col_name ) {
var select = jQuery("#leads_map").clone();
/* alter dropdown attributes */
select.attr( 'id' , col_name );
select.attr( 'style' , '' );
select.attr( 'name' , col_name );
/* attempt to preselect values if applicable */
/*** This is where I need help. My needle is col_name ****/
var select_html = select.prop('outerHTML');;
/* build html */
var html= '<div class="row">';
html += ' <div class="col-md-3">';
html += col_name;
html += ' </div>';
html += ' <div class="col-md-3">';
html += select_html;
html += ' </div>';
html += '</div>';
/* append html to map container */
jQuery('#map-container').append(html);
}
I tried your code in my pc and it's working very well. However I suggest this codes :
/* build html */
var html= '<div class="row">';
html += ' <div class="col-md-3">';
html += col_name;
html += ' </div>';
html += ' <div class="col-md-3">';
html += select_html;
html += ' </div>';
html += '</div>';
replace to this one :
var html = $('<div/>', { class: "row" });
$('<div/>', { class: "col-md-3", text: col_name }).appendTo(html);
$('<div/>', { class: "col-md-3", html: select_html }).appendTo(html);
In this way, reading of code will be easy and nice.
Also you can use $ mark instead of jQuery.

How to properly set the HTML contents using Jquery?

I have this javascript code where it goes for each movies in jsonp dataType. For each movies I have to display its thumbnail image and its title together with the star rating. To display the star symbols below for each movies I have this code:
var include = '<div class="rateit" data-rateit-value="2.5" data-rateit-ispreset="true" data-rateit-readonly="true"></div>';
$(".prediction").html(include); //DISPLAYS THE PREDICTION RATING
It simply sets the html content of the class prediction to this -> <div class="rateit" data-rateit-value="2.5" data-rateit-ispreset="true" data-rateit-readonly="true"></div>
I tried to use this on directly on my html code and it is fully working I can see the stars. Here it is:
But I tried this on javascript and it is not displaying. I just want to have ratings below for each and every movies.
This is my javascript code:
var html = '';
var count = 0;
$.each(data.movies, function(index, movie) {
html += '<div class="item col-xs-6 col-md-3">';
html += '<div class="thumbnail" style="min-height:320px;max-height:320px;">';
//add link here
html += '<a href="viewMovieDetails.php?id=' + movie.id + '">'
html += '<img src="' + movie.posters.detailed + '" style="width:175px; height: 230px;" class="img-responsive" alt="" ></a>';
html += '<div class="caption">';
html += '<h5>' + movie.title + '</h5>';
html += '<div class="prediction"></div>';
html += '</div></div></div>';
//set a delay (1second) for a call on rotten tomatoes api and
//store data on db
if(count > 5){
setTimeout(function() { storeDataOnDB(movie.id);; }, 1000);
count = 0;
}
else{
count++;
}
});
// Append movies
$('#movie_recommend').html(html);
var include = '<div class="rateit" data-rateit-value="2.5" data-rateit-ispreset="true" data-rateit-readonly="true"></div>';
$(".prediction").html(include); //DISPLAYS THE PREDICTION RATING
What do you think is wrong? Am I missing something? or is there other way to do it. Thanks for the help.
You should notify RateIt plugin, that new data is available, just add this:
$(".rateit").rateit();
after $(".prediction").html(include);

Saving JQuery-UI Sortable Connected Lists Custom Configuration to Local Cookie

Please Skip to Update #2 at the Bottom if you don't want to read the whole post.
I have created a customizable UI using jquery-ui connected lists:
http://jqueryui.com/sortable/#connect-lists
I now want to save the user's configuration of the UI to a cookie on their local machine so that the next time they load the page the layout they previously setup will be loaded, as discussed on this page:
http://devheart.org/articles/jquery-customizable-layout-using-drag-and-drop/
The problem is that after discussing how to save the custom configuration of multiple connected lists in part 2 of his writeup, he neglects to include multiple connected lists in part 3 where he implements the code into an actual design. I have been able to get everything on my page to work like the final example on that page, but whenever I try to modify the code to work with connected lists the page no longer works.
I understand the basic idea behind what the code is doing, but I don't know JavaScript and have had no success in modifying the code to work with connected lists. I'm hoping that someone who does know JavaScript will be able to easily modify the code below to work with connected lists like part 2 does.
Part 2 saves the order of multiple connected lists, but doesn't load external html pages with the corresponding name.
Part 3 loads external html pages with the corresponding names of the item, but only supports a single list.
Code for Connected Lists from Part 2:
// Load items
function loadItemsFromCookie(name)
{
if ( $.cookie(name) != null )
{
renderItems($.cookie(name), '#wrapper');
}
else
{
alert('No items saved in "' + name + '".');
}
}
// Render items
function renderItems(items, container)
{
var html = '';
var columns = items.split('|');
for ( var c in columns )
{
html += '<div class="column"><ul class="sortable-list">';
if ( columns[c] != '' )
{
var items = columns[c].split(',');
for ( var i in items )
{
html += '<li id="' + items[i] + '">Item ' + items[i] + '</li>';
}
}
html += '</ul></div>';
}
$('#' + container).html(html);
}
Code from part 3 that does not support connected lists (Trying to modify this to support connected lists):
// Get items
function getItems(id)
{
return $('#' + id + '-list').sortable('toArray').join(',');
}
// Render items
function renderItems(id, itemStr)
{
var list = $('#' + id + '-list');
var items = itemStr.split(',')
for ( var i in items )
{
html = '<li class="sortable-item';
if ( id == 'splash' )
{
html += ' col3 left';
}
html += '" id="' + items[i] + '"><div class="loader"></div></li>';
list.append(html);
// Load html file
$('#' + items[i]).load('content/' + items[i] + '.html');
}
}
Update #1:
I think I almost have it, I just can't get it to insert html from the external html files. It was able to get it to insert variables and plain text, just not the external html.
// Render items
function renderItems(items)
{
var html = '';
var columns = items.split('|');
for ( var c in columns )
{
html += '<div class="column';
if ( c == 0 )
{
html += ' first';
}
html += '"><ul class="sortable-list">';
if ( columns[c] != '' )
{
var items = columns[c].split(',');
for ( var i in items )
{
html += '<li class="sortable-item" id="' + items[i] + '">';
//---------This Line Isn't Working--------->
$('#' + items[i]).load(items[i] + '.html');
//---------This Line Isn't Working--------->
html += '</li>';
}
}
html += '</ul></div>';
}
$('#example-2-3').html(html);
}
Update #2:
I've been looking up exactly what each JavaScript command in the example does and I think I've figured out the problem. I can't just load the page, I need to append the code from the external page to the html variable. I think I need to use the .get command, something like:
var pagedata = '';
.get(items[i] + '.html', function(pagedata);
html += pagedata;
Anyone know what the correct syntax to accomplish this would be?
I finally got the code to work. Here is the full code (not including jquery-ui related code). External pages need to be named the same as the list id.
HTML
<div id="example-2-3">
<div class="column first">
<ul class="sortable-list">
<li class="sortable-item" id="id1"></li>
<li class="sortable-item" id="id2"></li>
<li class="sortable-item" id="id3"></li>
</ul>
</div>
<div class="column">
<ul class="sortable-list">
<li class="sortable-item" id="id4"></li>
</ul>
</div>
<div class="column">
<ul class="sortable-list">
<li class="sortable-item" id="id5"></li>
<li class="sortable-item" id="id6"></li>
</ul>
</div>
</div>
Script
$(document).ready(function(){
window.onload = loadItemsFromCookie('cookie-2');
// Get items
function getItems(exampleNr)
{
var columns = [];
$(exampleNr + ' ul.sortable-list').each(function(){
columns.push($(this).sortable('toArray').join(','));
});
return columns.join('|');
}
// Load items from cookie
function loadItemsFromCookie(name)
{
if ( $.cookie(name) != null )
{
renderItems($.cookie(name));
}
else
{
alert('No items saved in "' + name + '".');
}
}
// Render items
function renderItems(items)
{
var html = '';
var pagedata = '';
var columns = items.split('|');
for ( var c in columns )
{
html += '<div class="column';
if ( c == 0 )
{
html += ' first';
}
html += '"><ul class="sortable-list">';
if ( columns[c] != '' )
{
var items = columns[c].split(',');
for ( var i in items )
{
html += '<li class="sortable-item" id="' + items[i] + '">';
var pagedata = '';
var scriptUrl = items[i] + ".html"
$.ajax({
url: scriptUrl,
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
result = data;
html += data;
}
});
html += '</li>';
}
}
html += '</ul></div>';
}
$('#example-2-3').html(html);
}
$('#example-2-3 .sortable-list').sortable({
connectWith: '#example-2-3 .sortable-list',
update: function(){
$.cookie('cookie-2', getItems('#example-2-3'));
}
});
});
</script>

Categories