semantic ui popup working with manual/click - javascript

I need some advice on how to get this to work. My goal is to open a semantic popup manually after setting an angularjs scope variable. Let's say there are 5 images, I click each one. For every image I previously clicked, the popup doesn't open again. And then doesn't go away. I assume the best option for it not going away would be to have a timer/timeout to close it, but I am looking for a better option. I also have a table that uses the click event, and when clicking from one button to another, it just closes, and has similar issues related to not opening again.
So I am looking for features similar to:
manual open, but closes when clicking away
move popup to another control immediately on click event without closing it, but still close when clicking away from those controls.
Should I attempt inline instead? Table will have about 200 buttons, though it could have more, and this example could have even more. They are being used more like context menu.
Horrible first attempt at js fiddle: https://jsfiddle.net/3ecjecxn/22/
<div ng-repeat="page in Pages" class="item">
<div class="ui grid">
<a ng-if="page.Selected != null && page.Selected === true" class="twelve wide column active" ng-click="GetPageInfo(page.Id)"><span ng-repeat="n in range(page.Indention)"> </span>{{page.Name}}</a>
<a ng-if="page.Selected != null && page.Selected !== true" class="twelve wide column" ng-click="GetPageInfo(page.Id)"><span ng-repeat="n in range(page.Indention)"> </span>{{page.Name}}</a>
<div class="two wide column">
<!-- Settings icon by Icons8 -->
<img ng-click="SetTempPageId($event, page.Id)" class="pageCommand" src="[placeimagehere" width="20" height="20">
</div>
</div>
</div>
$(".pageCommand")
.popup({
popup: $('#PagePopup'),
on: 'manual',
delay: {
show: 0,
hide: 0
},
lastResort: 'bottom right',
movePopup: true,
closable: true,
prefer: 'opposite'
});
$scope.SetTempPageId = function ($event, id) {
$scope.EditingPageId = id;
$($event.target).popup('show');
};

Just now getting back to this, but soon after posting this answer, Instead of using semantic ui as context menu, I just used jquery contextmenu:
http://swisnl.github.io/jQuery-contextMenu/index.html
$.contextMenu({
selector: '.command',
callback: function (key, options) {
if (key == "Search") {
console.log("clicked search");
var search = $(".search").modal({ duration: 0 });
search.modal("show");
}
},
items: {
"Search": { name: "Search", icon: "search" }
}
});

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

ResponsiveTabs add onclick in js file

I am working with the ResponsiveTabs module from PeteLove.com.
http://www.petelove.com/responsiveTabs/
I would like to make a change into it because I need an onclick event added to the tabs. Now this should be done I believe in the following code section.
// CREATE TAB ITEMS (VISIBLE ON DESKTOP)
//create tab list item from heading
//associate tab list item with tab panel
var $tabListItem = $('<li/>', {
'class': 'responsive-tabs__list__item',
id: 'tablist' + tablistcount + '-tab' + tabcount,
'aria-controls': 'tablist' + tablistcount +'-panel' + tabcount,
'role': 'tab',
tabindex: 0,
text: $tabHeading.text(),
keydown: function (objEvent) {
if (objEvent.keyCode === 13) { // if user presses 'enter'
$tabListItem.click();
}
},
click: function() {
//Show associated panel
Now I expected to see somewhere <li> so that I could do <li onclick="setBrowserFrameSource(); return false;"> but there is no <li> anywhere just the closing brackets. So I should add it to the code above. I have tried to add it as follows:
'role': 'tab',
'onclick="setBrowserFrameSource(); return false;"',
tabindex: 0,
But this broke the entire thing. Any help would be appreciated. Thanks in advance.
According to the instructions from the website petelove.com (full link in original question) you need to start the tabs with:
<div class="responsive-tabs">
Then the plugin will do the rest. So I thought instead of adding for each <li> an onclick event why not add it to the container element. Which I did and it is working. So I now have the following.
<div class="responsive-tabs" onclick="setBrowserFrameSource(); return false;">
Now every time a tab is clicked it does its functions.

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){
});

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