ResponsiveTabs add onclick in js file - javascript

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.

Related

Summernote - Custom dropdown for ordered and unordered list

I am using Summernote editor v0.8.9 for quite a long time. I have created a custom dropdown button for Ordered List and Unordered List by using below code
let orderedList = function (context)
{
let ui = $.summernote.ui;
// create button
let button = ui.buttonGroup([
ui.button({
className: 'dropdown-toggle',
contents: '<i class="fa fa-list-ol"/><span class="note-icon-caret"></span>',
container: false,
tooltip: 'Ordered List',
data: {
toggle: 'dropdown'
}
}),
ui.dropdown({
className: 'dropdown-style',
contents: "<ol style='list-style-type:none' class='ordered-list'><li data-value='1'>1</li><li data-value='1' style='display: none;'>1)</li><li data-value='I'>I</li><li data-value='A'>A</li><li data-value='a)' style='display: none;'>a)</li><li data-value='a'>a</li><li data-value='i'>i</li></ol>",
callback: function ($dropdown) {
$dropdown.find('li').each(function () {
$(this).click(function() {
selectedListType = orderedListMap[$(this).attr('data-value')];
$(context).summernote('editor.insertOrderedList');
});
});
}
})
]);
return button.render(); // return button as jquery object
};
And also I get the dropdown attached to the toolbar as shown in the image
I have changed some code in the summernote.js to change the list style type after clicking on the dropdown item.
I am adding following code in the Bullet.prototype.wrapList method as follows
//for bullets and numbering style
if (selectedListType != 'NA') {
listNode.setAttribute('style', 'list-style-type:' + selectedListType);
}
I have also added the following code in the method "function replace(node, nodeName)" of "dom" object.
//for bullets and numbering style
if ((nodeName == 'OL' || nodeName == 'UL' ) && selectedListType != 'NA') {
$(newNode).css('list-style-type', selectedListType);
}
When I click on the dropdown item I am calling below code.
$(context).summernote('editor.insertOrderedList');
At first instance everything is working fine. I can change ordered list to unordered list as well as to other types of lists. But the problem arises when I am trying to create a new list. When I try to create a new list below the existing list (note : after double entering new line, existing list closes, hence a new list is created after double entering new line),
the focus does not stay on the current line. Instead it goes to the old list and old list style (Ordered/unordered) is getting changed.
I have also kept the default UL/OL in the toolbar for deugging and I can see that the document.selection() in the method WrappedRange.prototype.nativeRange is giving proper selection for default UL/OL but is giving wrong selection for my dropdown UL/OL.
Please help.
Let me know if any info is needed from my side
I solved this problem.
The problem was with the custom dropdown I created.
The dropdown needs to be in the following structure in the 'contents' attribute inside 'ui.dropdown'
<li>
</li>
<li>
</li>
'a' tag inside 'li' tag

semantic ui popup working with manual/click

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

Popover with MeteorJS

Try to use bootstrap popover with MeteorJS and have 2 troubles:
Can't assign some value that coming from collection to input value
I try to get one popover on html,body but have every popover on every template, it's normal, but I try to do only 1 popover on 1 screen
I have collection Posts with such documents Posts.insert({title:"Loli Pop"});
Meteor.publish("posts_levels", function(){
return Posts.find();
});
<template name="www">
{{#each level}}
{{> one}}
{{/each}}
</template>
Template.www.onCreated(function(){
var self = this;
self.autorun(function() {
self.subscribe('posts_levels');
});
});
<template name="one">
<div class="popover-markup">
<div class=" trigger ">
Edit
</div>
</div>
<div class="content-popover hide">
<form class="form">
<input name="title" id="post_edit_title" value="{{title}}" />
</form>
</div>
</template>
Template.one.onRendered(function(){
$('.popover-markup > .trigger').popover({
html : true,
content: function() {
return $('.content-popover').html();
},
container: 'body',
placement: 'right'
});
EDIT: 2 problem solved for 50%, I add this, and now it's hide when I open another popover, but then I must click 2x on .trigger to show new popover
$('.popover-markup > .trigger').popover({
html : true,
content: function() {
return $('.content-popover').html();
},
container: 'body',
placement: 'right'
}).on("click", function(e){
$('.trigger').not(this).popover('hide');
});
Here's an anwser for your question 1 (assign value from collection to input).
The input in the template gets the value of title. When you remove the hide class you can see the title from the collection. But a popover inserts new elements into the DOM. And those new elements are rendered by Bootstrap and not rendered by Blaze, so the input is not filled with the value of title.
What you can do is attach an event handler to the popover when it is shown. Something like this:
Template.one.onRendered(function(){
$('.popover-markup > .trigger').popover({
html: true,
content: function () {
return $('.content-popover').html();
},
container: 'body',
placement: 'auto top'
}).on('shown.bs.popover', function () {
$('.popover-content #post_edit_title').val(this.data.title);
}.bind(this));
});
As you can see the event shown.bs.popover can be used to do some initialization. In the event handler the value for the input is set.
It is important to have the jquery selector find your input in the popped form, that's why the selector starts with .popover-content. Otherwise it would set the value to the first input that was defined in the template.
Another thing to note is the use of bind(this). That attaches this and makes it usable inside the event handler so you can get the value of title.
BTW, there is also a hidden.bs.popover event when the popover is closing.

How to add multiple items to context menu in Kendo Scheduler?

"kendoContextMenu" is one of control from Telerik suit. I am trying to attach it with Kendo Scheduler control.
Below is the code to render scheduler and menu
Part of it taken from Kendo sample site
<div id="example">
<div id="scheduler"></div>
<ul id="contextMenu"></ul>
</div>
Here is Context Menu Initialization
$("#contextMenu").kendoContextMenu({
filter: ".k-event, .k-scheduler-table td",
target: "#scheduler",
select: function(e) {
var target = $(e.target);
if (target.hasClass("k-event")) {
var occurrenceByUid = scheduler.occurrenceByUid(target.data("uid"));
} else {
var slot = scheduler.slotByElement(target);
}
},
open: function(e) {
var menu = e.sender;
var text = $(e.target).hasClass("k-event") ? "Edit Title" : "Block";
menu.remove(".myClass");
menu.append([{text: text, cssClass: "myClass" }]);
}
});
});
The above code adds only ONE item in context menu and click event directly fires up. I would like to have multiple items in a context menu and each should have its own event so that I can use them as it clicked.
Below image shows right click behavior, where it shows only Block in a menu
I am trying to get menu as below- which has multiple items and have its own click events
I am trying like below by appending text but it's seems to be wrong way to do and it can not have separate click event.
open: function(e) {
var menu = e.sender;
var text = $(e.target).hasClass("k-event") ? "Edit event" : "Add Event";
text = text + "|" + "Cancel"
menu.remove(".myClass");
menu.append([{text: text, cssClass: "myClass" }]);
}
Kindly help
I'm afraid you're appending it wrong. By concatenating "| Cancel" you're not adding a new item, but adding text to the existing one.
Try creating a new object and append it with append():
menu.append([{text: "Cancel", cssClass: "cancel-opt" }]);
Then you check by the class inside the select event:
if (target.hasClass("cancel-opt"))

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