Change link inside jquery ui tab - jquery-ui

I'm trying to change the link text that is in a jquery tab but I'm getting empty value.
$.fn.addEditorTab = function(name, tabName, contents) {
$('ul', this).append('<li title="' + name + '">' + tabName + '<span class="ui-icon ui-icon-close" role="presentation"></li>');
$(this).append("<div id='tab-" + name + "'><div id='editor-" + name + "' class='editor'></div></div>");
$(this).tabs("refresh");
var selectedTabTitle = $("a#fileTabs .ui-tabs-active").text();
alert(selectedTabTitle); // empty string
}
I know I can get the .ui-tabs-active text as along it comes back but the a# I thought would get the anchor tag but looks like it doesn't. I'm not sure how to get the anchor tag I guess in the tab.
[EDIT]
I've been able to do the following but I don't like it:
var selectedTabTitle = $("#fileTabs .ui-tabs-active").text();
var selectedTabHtml = $("#fileTabs .ui-tabs-active").html();
$("#fileTabs .ui-tabs-active").html(selectedTabHtml.replace(">" + selectedTabTitle, ">*" + selectedTabTitle));

According your code. I see you are generating the tabs dynamic.
This element $("a#fileTabs .ui-tabs-active") doesn't exist.
None of your tabs active.
You need to active your tab first.
You can verify it by using this code to check the active tab exist
console.log($("a#fileTabs .ui-tabs-active").length)
Updated
Updated answer with requirement get/set/edit to change element's text of tab without changing it's child element
http://jsbin.com/kusujetaka/1/edit?html,js,output

Related

How to change absolute position of mat-menu in angular 4 material using x and y co-ordinates?

I have following menu in angular 4
<button mat-button [matMenuTriggerFor]="menu" style="display:none;">Menu</button>
<mat-menu #menu="matMenu">
<button mat-menu-item *ngFor="let item of items" (click)="select(item)">
{{ item }}
</button>
</mat-menu>
I am opening the menu when user selects text on screen using
matMenuTrigger.openMenu();
but I want to open menu wherever user selects text.
I have X and Y coordinates of user selection but how can I change position of menu?
I have tried giving Id to mat-menu and changing it's position using
element.style.position = 'absolute'
element.style.left = screenX + 'px'
element.style.top = screenY + 'px'
but it's not changing position of menu.
EDIT:
I have changed position of menu by
this.matMenuTrigger.openMenu();
var element = document.getElementsByClassName('cdk-overlay-pane');
menu.style.position = "absolute";
menu.style.left = evt.pageX + 5 + 'px';
menu.style.top = evt.pageY + 5 + 'px';
where evt is mouseup event which gives co-ordinates(X,Y) of user text selection.
But, when I scroll the page , opened menu again goes back to it's original position.
How can I keep menu to it's changed position on scroll??
I have implemented opening mat-menu where ever user selectes text.
I have added hidden button which on click opens menu.
On user text selection, I have changed style="display:none;" of that button to style="display:'';" and after showing that button, I have changed position of that button to where user has selected the text by x and y co-ordinates and then opened menu programatically by this.menuTrigger.openMenu();
DEMO
menu-example.ts
export class MenuIconsExample {
#ViewChild(MatMenuTrigger)
private menuTrigger: MatMenuTrigger;
addTextToOpns: Array<String> = ["option 1", "option 2", "option 3"];
selectedOption: string = "no Option selected";
onTextSelection(event: any):void{
if(window.getSelection && window.getSelection().toString()){
var menu = document.getElementById('menuBtn');
menu.style.display = '';
menu.style.position = 'absolute';
menu.style.left = event.pageX + 5 + 'px';
menu.style.top = event.pageY + 5 + 'px';
this.menuTrigger.openMenu();
}
}
onMenuClosed():void {
var menu = document.getElementById('menuBtn');
if (menu) {
menu.style.display = 'none';
}
}
addTextTo(selectedOpn): void {
this.selectedOption = selectedOpn + ' selected';
}
}
menu-example.html
<div (mouseup)="onTextSelection($event)">
<button mat-button [matMenuTriggerFor]="menu" id="menuBtn" style="display:none;">Menu</button>
<mat-menu #menu="matMenu" (close)="onMenuClosed()">
<button class="menuOpnBtn" mat-menu-item *ngFor="let opn of addTextToOpns" (click)="addTextTo(opn)">
{{ opn }}
</button>
</mat-menu>
<p>
text for selection
</p>
</div>
<br/>
<br/>
<div><span>selected option : </span> <span>{{selectedOption}}</span></div>
In order to get this example to work in a more general case, I found it necessary to use "menu.style.position = 'fixed' (rather than "menu.style.position = 'absolute').
This is because "event.pageX" returns the coordinates relative to the viewport. Since "position = absolute" positions the button relative to its containing parent, the position of the invisible button will be correct only if its containing parent is not already nested in some other HTML element.
So, to summarize, I changed the code for menu-example.ts as follows and it now seems to work in all cases:
export class MenuIconsExample {
#ViewChild(MatMenuTrigger)
private menuTrigger: MatMenuTrigger;
addTextToOpns: Array<String> = ["option 1", "option 2", "option 3"];
selectedOption: string = "no Option selected";
onTextSelection(event: any):void{
if(window.getSelection && window.getSelection().toString()){
var menu = document.getElementById('menuBtn');
menu.style.display = '';
menu.style.position = 'fixed';
menu.style.left = event.pageX + 5 + 'px';
menu.style.top = event.pageY + 5 + 'px';
this.menuTrigger.openMenu();
}
}
onMenuClosed():void {
var menu = document.getElementById('menuBtn');
if (menu) {
menu.style.display = 'none';
}
}
addTextTo(selectedOpn): void {
this.selectedOption = selectedOpn + ' selected';
}
}
Are you also foolishly wandering here like I wasted 3 hours of mine manually setting the position of mat-menu just because the triggering element of mat-menu disappears from the DOM on some condition and you don't want mat-menu to be closed at that time, then instead of using ngIf use hidden property on that triggering element, it will save your ton of time of creating some hidden element, displaying it first, getting its coordinates bla bla bla, may be that will save someones life
The OP has edited the question to include the best answer for moving the menu position.
However, in the newer versions of angular, doing a document.getElementsByClassName returns a HTMLCollection and when accessing the element, it does not have the style property. I think this is because of the update to typescript.
I found this article which helped with it (Property 'style' does not exist on type 'Element' in TS)
The final result is this (note the setTimeout. This is done so that the mat menu can be rendered before it is moved)
this.matMenuTrigger.openMenu();
setTimeout(() => {
const menuCollection = document.getElementsByClassName('cdk-overlay-pane') as HTMLCollectionOf<HTMLElement>;
const menu = menuCollection[0];
menu.style.position = 'absolute';
menu.style.left = e.x + 5 + 'px';
menu.style.top = e.y + 5 + 'px';
}, 0);

Create new jquery ui tab panel with close button inside the panel?

I've got a function worked out that creates a new query ui tab panel when a user clicks a button. It also creates a new tab with a close button in it, like so:
$(function newTab() {
var $tabs = $('#nav-tabs').tabs();
$('.add-tab').click(function (e) {
e.preventDefault()
var tabName = $(this).text(),
tabLink = $(this).attr('href'),
tabNumber = -1;
$tabs.find('.nav-tab-menu li a').each(function (i) {
if ($(this).text() == tabName) {
tabNumber = i;
}
});
if (tabNumber >= 0) {
$tabs.tabs('option', 'active', tabNumber)
} else {
$("<li><a href=" + tabLink + " class='ui-icon-tab-add'>" + tabName + "</a><span class='ui-icon-close' role='presentation'><span class='sr'>Remove Tab</span></span></li>")
.appendTo(".nav-tab-menu");
$("#nav-tabs").tabs("refresh");
$('#nav-tabs').tabs('option', 'active', -1);
}
return false
})
});
It works great, but this client is a total pain in the ass, and one close button isn't good enough for them - they also want one in the newly created panel as well. I've tried cloning the button and appending it to the panel, but it doesn't seem to work. Any ideas? I should mention that the content of the current tab is replaced when the user clicks a link, so the button probably needs to be inserted before the active tab panel, rather than inside it so it doesn't get removed when the content is updated.

Dynamically change color of jQuery Mobile collapsible

I have a method used in an onclick handler, from within the content of a collapsible in jQuery Mobile.
The idea of this method is to access the collapsible and make the collapsible button green to mark it as ok, when viewing the collapsible set with all items collapsed.
No matter what i've tried i have had no success in this.
I have tried to add a custom theme file and call .attr("data-theme", "b") for instance, to no avail. I have also tried to add a custom class, that does not work.
The thing is, it is dynamic so when page is first switched to it does not have any custom styling. Only upon clicking an element in the content of collapsible X should X be turned to green backcolor.
When inspecting the element when run i can see that it appends the new attributes and/or correctly, but it does not render.
I tried calling .trigger("create") on the element as well after appending styles, to no avail.
Example of something i tried. The element is given an id of "Stop" + id when dynamically inserted into the set, i just use that to find the correct element to attempt to style. This works and i can see that it is appended to the correct element.
function markAsOk(id, index)
{
//Color the line green, use set id (computed, less costly than find by attribute value , switch to swatch B = green
$( "#Stop" + id ).attr("data-theme", "b");
$( "#Stop" + id ).attr("data-content-theme", "b");
//$( "#Stop" + id ).enhanceWithin(); */
$( "#Stop" + id ).trigger("create");
//Refresh main list
$( "#activestopslist" ).trigger("create");
}
above this the collapsible is declared dynamically as follows:
html += "<div data-role=\"collapsible\" id=\"Stop" + activeObj.id + "\" data-wonum =
\"" + activeObj.id + "\" data-index = \"" + activeObj.index + "\">";
//Set content
html += "<h3>" + activeObj.name + "</h3>";
html += "<a href=# onclick=\"markAsOk(" + activeObj.id + "," + activeObj.index +
")\"><img src = \"resources/okicon.png\" /></a> <img src=\"resources/failicon.png\">";
//Icons for buttons
html += "<p>" + processInstructions(activeObj.instructions) + "</p>";
//End tag
html += "</div>";
Here you also see the onclick event, added to the ok button embedded in content...
I would need some suggestions, it seems.
If you are just trying to change the color of the collapsible header, you don't need a theme swatch. Instead create a CSS rule for the green coloring, e.g:
.greenCollHeader {
background-color: #7FAF1B !important;
text-shadow: #aaa 0 1px 0 !important;
}
Then on your image click, just add this class to the link with class .ui-collapsible-heading-toggle within the collapsible widget:
$("#Stop" + id).find(".ui-collapsible-heading-toggle").addClass("greenCollHeader");
DEMO

Run jQuery code in a non-selected jQuery-UI tab - 1.10

I am trying to run jQuery code on elements contained within a jQuery tab which is not selected. If i quickly click the tab before the Ajax loading has completed it works, but if i leave it running without being selected the code will not be executed.
As ou can see below, the tab i want to load data into were not defined from the beginning, it was created when the user clicked a button.
The functionality i want to achieve is tabs, where the user will search for X in the start tab, then the new tab is created, content is loaded in the background (needs jQuery code for grids and format). Then the user can click the tab and see the results.
jQuery 1.10
jQuery-UI 1.10
Example:
<script>
$(document).ready(function(){
var myindex = 1;
$("#startsearch").click(function() {
search = escape(($("#search").val()));
searchdate = ($.datepicker.formatDate('yy-mm-dd', new Date()));
var tabs = $( "#tabs" ).tabs();
var ul = tabs.find( "ul" );
// Add new tab
newhtml = "<li id='henrik_tab_" + myindex + "Selector'><a href='#henrik_tab_" + myindex + "'>Search: " + searchdate + "</a></li>";
newhtml2 = "<div id='henrik_tab_" + myindex + "'></div>";
ul.append(newhtml);
tabs.append(newhtml2);
tabs.tabs( "refresh" );
// Load data into tab
$( "#henrik_tab_" + myindex).load("dosearch.php?data=" + search, function(responseTxt,statusTxt,xhr) {
if(statusTxt=="success") {
!! DOING STUFF WITH ELEMENTS CONTAINED IN THE NEW TAB HERE !!
}
if(statusTxt=="error")
alert("Error: "+xhr.status+": "+xhr.statusText);
});
// increse the counter for next tab
myindex++;
});
$( "#tabs" ).tabs();
});
</script>
Any help would be much appreciated.
Try change code
tabs.append(newhtml2);
to
$( "#tabs" ).append(newhtml2);
If not fix, would like show the code should be executed but not.

jQuery UI api - Tabs - getting selected

I couldn't find what I'm doing wrong here...
I'm trying to apply some effect on the selected <li> of the navigation, I'm getting the index of it but I can't apply anything on it :
$("#tabs").bind('tabsselect', function(event, ui) {
var choosen = ui.index;
console.log(choosen);
$('#tabs ul').find('li:eq(choosen)').toggleClass('selectedone');
});
at a guess it looks like you are sending the string choosen to the find function rather than the value of choosen - so I would say you need to try instead
$('#tabs ul').find('li:eq(' + choosen + ')').toggleClass('selectedone');

Resources