Load DIVs with same class into a modal dialog - javascript

I'm creating a fairly simple FAQ system to overhaul my company's outdated one. The page layout is very basic:
<div class="faq_c"> // Container
<div class="faq_q">Question Goes Here</div> // Question -- clicking this should open the Answer div in a dialog
<div class="faq_a">Answer Goes Here</div> // Answer
</div>
The faq_a class has display:none set in CSS to hide it.
What I'm wanting to do is have each faq_a load into a modal dialog when the parent faq_q class DIV is clicked. The structure of the modal should be:
Question
--------- // Horizontal Rule formatted with CSS
Answer
jQuery (Revised)
$(document).ready(function(){
$('.faq_a').each(function(){
$('.faq_a').dialog({
autoOpen: false,
modal: true,
resizable: false,
draggable: false,
overflow: scroll,
title: "Frequently Asked Question",
width: 500
});
$('.faq_q').click(function(){
$('.faq_a').dialog('open');
});
});
});
This isn't working exactly correctly. Instead of opening the single desired faq_a it's opening all of them. I also can't figure out how to get the desired layout inside the div.
Thanks in advance.

Looks like you just need to fix your selector:
jsFiddle
//var $dialog = $('<div>' + $('.faq_q') + '<hr>' + $('.faq_a') + '</div>'); // bad
var $dialog = $('div, .faq_q, hr, .faq_a');// good
$dialog.click(function() {
alert('clicked');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
click me
</div>

Related

Can Bootstrap popovers not be destroyed?

Is it possible to have a bootstrap (v3) popovers to have it's div loaded right at the start of pageload and not be destroyed when it is being toggled?
I have a popover content in a div:
<div id="popoverContent">
<h1>Stuff</h1>
<p>I'm in a popover!</p>
</div>
And a button that toggles the popover:
<a id="floating_tab" data-toggle="popover" data-placement="left">Button</a>
Here is my Javascript code that handles the button pushes:
<script>
var x = false;
$('[data-toggle=popover]').popover({
content: $('#popoverContent').html(),
html: true
}).click(function() {
if (x) {
$(this).popover('hide');
x = false;
}
else {
$(this).popover('show');
x = true;
}
});
</script>
The thing is, that when $(this).popover('show'); is called, a div is created. Something like this shows up in the inspect element (chrome):
<div class="popover fade left in" role="tooltip" id="popover460185" style="top: 430.5px; left: 2234px; display: block;"><div class="arrow" style="top: 50%;"></div><h3 class="popover-title" style="display: none;"></h3><div class="popover-content">
<h1>Stuff</h1>
<p>I'm in a popover!</p>
</div></div>
But when the button is clicked again, the whole div itself is removed and obliterated from the page.
Is it possible to have the popover div to be created during pageload (hidden though) and can be toggleable without having the div to be deleted?
As stated in the comments, it is not presently possible with Bootstrap 3. The Popover (which is an extension of the Tooltip) is dynamically created on show and detached (using jQuery.detach) from the DOM on hide.
It is probably best to roll your own JavaScript and simply utilize Bootstrap's CSS. However, you could easily patch the functionality using the Popover's event API -the following can be used as a starting place:
$(function () {
var content = $('#popover-content'), // Pre defined popover content.
popover = $('#popover-anchor').popover();
popover.on('inserted.bs.popover', function () {
var instance = $(this).data('bs.popover');
// Replace the popover's content element with the 'content' element
instance.$tip = content;
});
popover.on('shown.bs.popover', function () {
var instance = $(this).data('bs.popover');
// Remove the reference to 'content', so that it is not detached on hide
instance.$tip = null;
});
popover.on('hide.bs.popover', function () {
// Manually hide the popover, since we removed the reference to 'content'
content.removeClass('in');
content.addClass('out');
});
});
Codepen

Create a custom popup that is responsive and can post to database

I am currently working on an intranet solution for my company written in PHP using the Laravel framework, this requires me to do a lot of new things I have never done before, 1 of these is creating a popup that has dynamic html depending on a drop down list such as this:
I have a calendar (http://fullcalendar.io/)
When I click on a day in this calendar a popup should show that looks something like this:
After selecting a value from that dropdown list a different set of fields should be shown depending on the value selected for example:
OR
So I really need a lot of control over the popup, I have no previous experience with working with popups (unless a simple alert of a variable in javascript counts) and I need a whole deal of functionality, it also needs to be able to post to a database so I think it might even have to be a form element. I also need to be able to fire the popup from the onclick event from the fields in my calendar so that makes it extra hard for someone who has always written back end code up until now.
SO WHAT IS YOUR QUESTION?
Could anyone tell me what the easiest/fastest way to achieve this is without losing any functionality necessities, can I do this from php, does a feature like this exist in the Laravel framework?(if it does I coudldn't find it) or do I have to start using something like jquery?
I found a bunch of libraries such as Fancybox that claim to be able to do this but I can't make head nor tail out of their usage guide.
For everyone who thinks this doesn't belong here: my only question is not "Is it Possible?" I am also asking how do I do it, what do I write in my html, javascript, php to make it work?
EDIT: I just read something about jquery dialogs that seems interesting, seems like you can use jquery dialogs to create a popup from a form you have in your html (form is hidden) but I can't seem to get the code to fire off the popup (dialog) to work so far I have this:
$(document).ready(function() {
$('#calendar').fullCalendar({
//calendar options here
dayClick: function(date, jsEvent, view) {
//to get date use date.format());
//POPUPCODE START
$("#logform").dialog({ //Shows dialog
height: 250,
width: 450,
modal: true,
buttons: {
"Cancel": function() {
$( this ).dialog( "close" );
},
"Save": function() {
$.ajax({
url: "/url/to/submit", //
timeout: 30000,
type: "POST",
data: $('#modalform').serialize(),
dataType: 'json',
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred making the request: " + errorThrown)
},
success: function(data){
//Do stuff here on success such as modal info
$( this ).dialog( "close" );
}
}
}
}
}),
//POPUPCODE END
var myCalendar = $('#calendar');
myCalendar.fullCalendar();
var myEvent = {
title:"Work 7.6h",
allDay: true,
start: date,
end: date
};
myCalendar.fullCalendar( 'renderEvent', myEvent,true );
},
eventClick: function(calEvent, jsEvent, view) {
var myCalendar = $('#calendar');
myCalendar.fullCalendar('removeEvents',calEvent._id);
}
})
});
And for my html I have:
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Calendar</div>
<div class="panel-body">
<div id='calendar'></div>
<a class='iframe' href='home.blade.php'>Click me</a>
</div>
<form id="logform" style="display:none">
<input type="text" name="something">
<input type="text" name="somethingelse">
</form>
</div>
</div>
</div>
</div>
The trouble started only after adding the code between //popupcode start and //popupcode end now my calendar won't even show and I get
SyntaxError: missing ) after argument list
The place it is pointing at is the 3rd line above my //popupcode end here:
}
}
} //this one
}
}),
//POPUPCODE END
But no matter what I add or remove there I keep getting the same error
I figured it out myself, instead of making things harder by learning all kinds of new things I got it to work by removing all the code I added previously and adding 1 line of code to create the popup by using jquery.
I removed all the code that I was using to create the popup and replaced it by this: $("#somediv").load().dialog({modal:true});
I created a div called 'somediv' around my form and now it's doing what I need it to do, seeing as my entire form is in the popup now I'm pretty sure I can add a button to it that can submit the form so I can catch that with php and then I'll be able to do whatever I want with the data in php (post to database or return error messages etc...)
Ok, first of all, i recommend to use Javascript.
It's possible with only PHP, HTML and CSS but you will have to refresh the page all the time for the next popup to appear.
You can just make divs that are positioned fixed or absolute and they will overlay the underlaying content. The overlaying div(popup) will be a normal div where you can make forms and whatever you want.
Here is a quick jsfiddle I threw toghether:
http://jsfiddle.net/0zvqm5nr/17/
Here is the code:
HTML
<div class="calendar">
<h1>Your calendar would be here</h1>
<button id="popupButton">13.05.2015</button>
</div>
<div class="popup">
<h2>13.05.2015</h2>
Activity:
<form action="site.php" method="post">
<select id="activity">
<option class="placeholder" selected disabled>Select</option>
<option>work</option>
<option>youth leave</option>
</select>
</form>
</div>
<div class="popup">
<h3>Work 13.05.2015</h3>
this will be the work popup
</div>
<div class="popup">
<h3>Youth leave 13.05.2015</h3>
this will be the youth leave popup
</div>
CSS
.calendar {
width: 500px;
height: 500px;
background: green;
}
.popup {
width: 500px;
height: 500px;
background: grey;
display: none;
position: fixed;
top: 0;
left: 0;
}
Javascript
document.getElementById("popupButton").onclick = function() {
document.getElementsByClassName("popup")[0].style.display = "block"
}
document.getElementById("activity").onchange = function() {
document.getElementsByClassName("popup")[0].style.display = "none"
var selectedValue = this.options[this.selectedIndex].innerHTML;
if (selectedValue == "work") {
document.getElementsByClassName("popup")[1].style.display = "block";
}
if (selectedValue == "youth leave") {
document.getElementsByClassName("popup")[2].style.display = "block";
}
}
I hope this helped.

JQuery closest() + find() tree traversal

Given a structure like this:
<div class="portlet">
<div class="portlet-config">
<p>Some configuration</p>
</div>
<div class="portlet-header">Configurable portlet</div>
<div class="portlet-content">This has a configuration window. Click on pencil icon to open.</div>
</div>
First, I append these DIVs to portlet-header (to display some buttons)
<div class="portlet-button-container">
<div class="portlet-button portlet-btn-delete ui-icon ui-icon-close"></div>
<div class="portlet-button portlet-btn-toggle ui-icon ui-icon-minusthick"></div>
<div class="portlet-button portlet-btn-config ui-icon ui-icon-pencil"></div>
</div>
Then I apply a jquery-ui dialog() plugin to the portlet-config DIVs
$(".portlet-config").dialog({
autoOpen: false,
show: {
effect: "fade",
duration: 200
},
hide: {
effect: "fade",
duration: 500
},
modal: true,
buttons: {
Ok: function () {
$(this).dialog("close");
}
}
});
Then I add come click handlers
$(".portlet-btn-toggle").click(function () {
var icon = $(this);
icon.toggleClass("ui-icon-minusthick ui-icon-plusthick");
icon.closest(".portlet").find(".portlet-content").toggle();
});
$(".portlet-btn-delete").click(function () {
var icon = $(this);
icon.closest(".portlet").hide();
});
$(".portlet-btn-config").click(function () {
var icon = $(this);
icon.closest(".portlet").find(".portlet-config").dialog("open");
});
It seems that the portlet-config DIV could not be found when the user clicks on the pencil.
More precisely it seems that:
$(this) // OK, returns an object
$(this).closest(".portlet") // OK, returns an object
$(this).closest(".portlet").find(".portlet-config") // NOK, returns null
Here is a fiddle to reproduce the problem: http://jsfiddle.net/silenzioso/M6LmS/
Thanks in advance
Your call to $(".portlet-config").dialog is doing a little more than you expect it to. If you look in the DOM, you can see that the div has been moved out of its original location and added to the end of the document. Presumably it does this for the overlayed dialog effect.
You could consider putting a unique ID on the dialog div so that you can find it again. Perhaps you could use a data attribute to store the associated dialog div ID in the button.
<div class="portlet">
<div class="portlet-config" id="dialog1">
<p>Some configuration</p>
</div>
<div class='portlet-button' data-config="dialog1"></div>
</div>
...
var id = $(this).data('config');
var config = $('#'+id);
If You are dynamically creating new DOM elements in jQuery make sure You add event click on body or document or other element that is defined from the very first page display (I mean server response):
$('body').on('click', '.portlet-btn-config', function(e){
});

Html Popup With Links On Form Submit

I am trying to display a fancy html popup/frame (not windows style) to the customer when a particular form is submitted. Not sure what would be the best way of doing that!
I tried something with the code below but there are 2 issues with this. Firstly the box that comes as a popup looks like a windows popup box (browser type) which I don't want. I just want a simple square box where I can add colors, image etc. Another problem is that my links within this code are not working. For eg. I want one of the links to take me to another page on the site after closing the message box, and the other link could simple be used to close the box... or may be just 2 links that could take me to 2 different pages!
<form action="do.something" method="post" onsubmit="return action_submitted();">
<script type="text/javascript">
function action_submitted() {
HTML = '';
HTML += '<html><head><title>New Action</title></head>';
HTML += '<body bgcolor="#f5f5f5" style="margin:0px;">';
HTML += 'Congrats, your action was successful! <br/>';
HTML += 'Close Message<br/>';
HTML += 'There<br/>';
HTML += '<script>onload=function(){setTimeout("self.close()",5000);}<'+'/script>';
HTML += '</body></html>';
var w = 500;
var h = 200;
var l = (screen.availWidth - w) / 2;
var t = (screen.availHeight - h) / 2;
actionwin = open('javascript:opener.HTML','actionwin','left='+l+',top='+t+',width='+w+',height='+h+',status=0');
if (actionwin && !actionwin.closed) actionwin.focus();
return true;
}
</script>
Please help :)
Many thanks!
try using jquery modal dialog:
var modal = "<div id='modal_pop'>" +
"<div><center ><img id='imgLogo' src='../../Images/abc.PNG' alt='Value Interface'/></center></div>" +
"<p>This is a fancy modal pop up.</p>" +
"</div>";
and call the modal dialog
$(modal).dialog({
modal: true,
width: 400,
height: opts.windowHeight,
closeOnEscape: false,
draggable: false,
resizable: false,
zIndex: 99999,
bgiframe: true,
title: Sample!',
buttons: {
"OK": function () {
// your action on OK clikc
$(this).dialog('close');
},
"Cancel": function () {
$(this).dialog('close');
}
}
});
more info on this site.
I suggest you need to create popup div in HTML at bottom of body. Hide popup by default By CSS and when you want to open it, then make it visible by javascript and pass content you do want to display if you have dynamic content.
HTML
<div id="popupWrapper">
<div id="popup">
content goes here
</div>
</div>
CSS
#popupWrapper { display: none;}
jQuery
$('#button').live('click', function() {
$('#popup').text('content goes here');
$('#popupWrapper').fadeIn();
});
Because in your case you are creating poup every time you click on button. which is not good way to do it.
Also don't use any other plugin because it's not good to use third party plugin for simple stuffs like that. It's make your project more complicated and slow. Because they design for multiple situations with multiple options, and if you not need that mean it's worth to use that plugin.

Activate Current Content Part in jQuery UI Accordion Menu

I'm trying to figure out how to dynamically activate the correct content part of a jQuery UI Accordion menu depending on the page currently being viewed. I've searched extensively and it seems like others have had issues with this in the past, but I haven't yet found a solution that works for me. I know that active can be set to open a certain index of the menu, but I need to do this dynamically.
I'm thinking that I can achieve what I want using the activate method, I just can't seem to figure it out. I'd like to stay away from setting cookies as that usually won't work with back/forward buttons and direct navigation via a specific url. Anyone have any ideas? Thanks in advance!
Here is the simplified structure of my menu:
<div id="menu">
<div id="sections">
<div class="grouping accordion">
<a id="heading1" href="#">Heading #1</a>
<div class="sub-items">
Item #1
<br />
Item #2
</div>
</div>
<div class="grouping accordion">
<a id="heading2" href="#">Heading #2</a>
<div class="sub-items">
Item #4
<br />
Item #6
</div>
</div>
</div>
</div>
And here is my jQuery Accordion init:
$('#sections').accordion({
header: '> .accordion > a',
autoHeight: false,
collapsible: true,
active: false,
animated: 'slide'
});
So if you are currently on the /item4 page for example, the group under Heading #2 should be expanded.
EDIT:
I found what seems to be a pretty good solution and posted that as an answer below, hopefully this will help someone with a similar problem!
To activate a specific tab, you'll want to use the accordion('activate', index) method. Example:
$( "#sections" ).accordion('activate', 2);
However, you will need something that defines an index key per page. You can probably even generate this dynamically. I would probably create a Pages object:
Pages = {
"heading1" : {
"id": 1,
"is_active": false,
"items": {
"item1": {
"href": "item1",
"name": "Item #1"
},
"item2": {
"href": "item2",
"name": "Item #2"
}
}
},
"heading2" : {
/* etc*/
},
}
With some hackish jQuery magic, you can loop through your headings
var active_heading_index = null;
$.each(Pages, function(heading) {
$.each(heading.items, function(item) {
if($(location).attr('href') == item.href) {
heading.is_active = true;
// or
active_heading_index = heading.id
}
});
});
if(active_heading_index) $( "#sections" ).accordion('activate', active_heading_index);
Anyhow, I'm sure there are cleaner and more efficient ways of doing it.
While working on some CSS for the active headings on the menu I stumbled on a pretty clean and easy solution. Looks like I might have been overthinking things!
Using the same HTML as in the question, here's the JavaScript that is working for me:
//accordion menu
$('#sections').accordion({
header: '> .accordion > a',
autoHeight: false,
collapsible: true,
active: '.selected',
animated: 'slide'
});
//add currentPage class to current menu item based on url
var url = window.location.href;
url = url.substr(url.lastIndexOf("/") + 1);
$("#sections").find("a[href='" + url + "']").addClass("currentPage");
//get id of header anchor tag
var headerId = $(".currentPage").parents(".accordion").children("a").attr("id");
//check if headerId is set, if so activate that id
if (headerId) {
$('#sections').accordion('option', 'animated', false);
$('#sections').accordion('activate', $('#' + headerId));
$('#sections').accordion('option', 'animated', 'slide');
}
This solution is pretty simple, it gets the current page from the url and compares it against each link in the accordion menu. If it finds a match, it gives that link a class of currentPage (which allows us to then style that link accordingly via css). Then it looks for a parent of that link with a class of .accordion, finds the first child link (the accordion header) and grabs the header's id. Assuming a header id has been found, we can then use the activate method to expand the correct section.
If you are going back to the server for every page click (standard non Ajaxy way), the server can add a "selected" class to the proper node. So you'd get back something like this at the client (I'm only writing the essential code, skipping most of the labels).
<ul id="menu">
<li>
<ul>
<li>
</li>
<li class="selected">
Menu 102
</li>
<ul>
</li>
<li>
...
</li>
<ul>
Then simply find the proper index to give to the activate property of the accordion.
$(document).ready(function() {
var index = $("li.selected").parents("li").last().index();
$("#menu").accordion({
active: index,
collapsible: true
});
});
The parents("li").last() jQuery returns the top most element. This only works if you only have one sub element with the class "selected", which should be the case for your menu.
I did it using this code:
var newsNum = parseInt(window.location.hash.slice(1));
$(document).ready(function(){
$("#menu").accordion('activate', newsNum );
});
And the url looks like example.com/index.html#1

Categories

Resources