Arranging the list based on the count bubble value - jquery-mobile

I have a collapsible list and list view attached to each collapsible set.
And in each collapsible set I am displaying the value of the number of list elements attached to each collapsible set.
I am creating the collapsible set dynamically as
div = '<div data-role="collapsible" data-inset="false" data-iconpos="right" data-collapsible="true" data-collapsed-icon="arrow-r" data-expanded-icon="arrow-d"><h3>' + row['name'] + '<span class="ui-li-count ui-btn-up-c ui-btn-corner-all" data-iconpos="right">' + count + '</span></h3></div>';
Now based on my count value I need to align my collapsible set.
Eg: If I have collapsible set with 3 elements
say , class A 1 ,class B 2 , class C 4 , class D 3
then my collapsible set should look like
class C 4
class D 3
class B 2
Class A 1
How can I do it?
Thanks:)

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

Making an asterisk in a label red

I have the following .html markup
.html
<paper-button
raised
active
toggles
on-tap = "toggler"
class = "bold">Patient *
<iron-icon
icon = ""
id = "fe-icon"></iron-icon>
</paper-button>
</div>
How can I make the * in Patient * red without the entire label being red, and also make the asterisk larger?
Just wrap it with a <span> like >Patient <span class="asterisk">*</span></iron-icon> then you can style it individually.

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

Control group loses control after dynamic add of radio button - jQuery Mobile

My control group (jquery mobile 1.4) renders perfectly when dynamically creating the radio group initially, but when I add another radio to it, the buttons are styled, but separated. When I reload the app, they are together again.
function showPlaces() {
$('#radio-group').empty();
for(var i = 0; i < connections.length; i++) {
$('#radio-group').append('<label><input type="radio" name="places" id="' + i + '" />' + place + '</label>');
}
$('input[type=radio]').checkboxradio().trigger('create');
$('#radio-group').controlgroup().trigger('create');
}
// The function is called when app starts, and again after I add another place
Some other things I've tried:
$("#radio-group").controlgroup("refresh");
$('#radio-group').controlgroup('refresh');
$("[data-role=controlgroup]").controlgroup("refresh");
$('input[type=radio]').checkboxradio('refresh');
Also tried .controlgroup('container'), before the .append, but get "cannot call methods on controlgroup prior to initialization".
Here's the html:
<form>
<fieldset data-role="controlgroup" id="radio-group">
<!-- Dynamically injected radio buttons go here -->
</fieldset>
</form>
You should .append() items into .controlgroup("container") inside for loop, and then enhance radio buttons .checkboxradio().
for(var i = 0; i < connections.length; i++) {
$('#radio-group')
.controlgroup("container")
.append('<label><input type="radio" name="places" id="+i+" />Place</label>');
}
$("#radio-group")
.enhanceWithin()
.controlgroup("refresh");
You dont even need to use .checkboxradio(), instead use .enhanceWithin() on parent container.
Demo

How to get the index of the element selected in ListView JQUERYMOBILE

I have created a dynamic listview with a link with id="a".
<ul id="accpmenu" data-role="listview" >
</ul>
$("#accpmenu").append('<li>'+ this.textContent +' </li>');
Now i want to identify the index of the element that I have clicked from this listview.
$("#a").live("click",function(e)
{
//What should i write here to get the selected index?.
}
I want the index number based on this I need to load the dynamic XML.
Please help me in resolving this.
Thanks
Shyam
$('#accpmenu').on('click', ' > li', function () {
var selected_index = $(this).index();
});
Here is a demo: http://jsfiddle.net/w2JZU/
This will bind an event handler to the list-items in the #accpmenu list for the click event that finds the index of the clicked list-item (compared to other list-item elements).
On a side-note you have what appears to be some invalid HTML in your code:
$("#accpmenu").append('<li>'+ this.textContent +' </li>');
Should change to (notice the removed double-quote after the id attribute):
$("#accpmenu").append('<li>'+ this.textContent +' </li>');
My example above added the click event handler to the li elements since it is easy to ascertain the index of the clicked element but you can also bind to links in the list:
$('#accpmenu').on('click', 'a', function () {
//this gets the index by finding the first parent list-item element and getting it's index compared do its siblings
var selected_index = $(this).parents('li').eq(0).index();
});
Note that .on() is new in jQuery 1.7 and in the cases above replaces .delegate() (from earlier versions).
Here are some docs for ya to help explain the above examples:
.on(): http://api.jquery.com/on
.index(): http://api.jquery.com/index
.parents(): http://api.jquery.com/parents

Resources