dynamically generated buttons with javascript - javascript

I am working on a TV application with JavaScript, Html and CSS.
I want to generate buttons where the label(title) is not always the same: sometimes so long or quiet short. The labels should be dynamically generated from xml files. So the problem is to display all the generated buttons with the same width.
Here is how I am creating the buttons with javascript:
var a = document.createElement("a");
var span2 = document.createElement("span");
span2.setAttribute("class", "span1");
span2.appendChild(document.createTextNode(text));
a.appendChild(span2);
How we can do it?

Here's an option:
When you get your set of button labels, get the length of each string.
Determine how wide the buttons need to be based on the number of characters in the longest string.
When you build each span2, give it a width attribute equal to that largest size.
However, be aware that if you have some very long labels and some very short, it may look weird having the really short labels on very wide buttons.

I don't know exactly what you are trying to do but here is one example how to make the buttons with same width and having different character length :)
var words = ['Lorem', 'Lorem ipsum', 'Lorem ipsum dolor', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit amet', 'Lorem ipsum dolor sit amet consectetur', 'Lorem ipsum dolor sit amet consectetur adipisicing', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit fuga', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit fuga animi'];
for (var i = 0; i < 10; i++) {
var a = document.createElement("a");
var span2 = document.createElement("span");
span2.setAttribute("class", "span1");
span2.style.width = 150 + "px";
span2.appendChild(document.createTextNode(words[i]));
a.appendChild(span2);
document.body.appendChild(a);
}
.span1 {
display: inline-block;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
text-align: center;
background: lightblue;
margin: 5px;
vertical-align: middle;
padding: 5px;
border-radius: 5px;
color: #fff;
}

Thanks a lot for your ideas and comments :)
I decided to make some thumbnails and I will query the buttons title :) At least I am sure now that I will get a list of buttons with fixed width.
Thanks a lot for your kind help :)

Related

How can I port the part of a Google maps application that uses infobubble.js to use Leaflet?

I am trying to port an old application that has a Google maps plugin, and uses infobubble.js to display popups on the map to use Leaflet instead.
I have got most of it working, but I'm not sure how to tackle the part that uses infobubble.js. In particular, it uses the tabs features of infobubble e.g. infoBubble.addTab() to attach several different bits of html information to one location / marker.
I've looked through the leaflet plugins at https://leafletjs.com/plugins.html and haven't been able to find anything that looks suitable.
I found the source code for infobubble.js at https://github.com/googlearchive/js-info-bubble, but porting that to Leaflet seems beyond my limited javascript abilities.
I've also considered making a simple replacement, but most references to creating tabbed content seem to suggest using jquery to manage the tabs, but (again, with my limited skills) I'm not sure whether that would work, or how to do that with html that is only displayed in a popup.
You don't need any jquery for that. A small library is enough. Take a look at this tabby and here is an example of how to use it - example
All you need to do when building a popup in leaflejs is the appropriate html and that's it. The only thing you have to do is move the tabs behind the popup outline with css.
/* eslint-disable no-undef */
/**
* tabs in popup
*/
// config map
let config = {
minZoom: 1,
maxZomm: 18,
};
// magnification with which the map will start
const zoom = 15;
// co-ordinates
const lat = 50.0595;
const lng = 19.9379;
// calling map
const map = L.map("map", config).setView([lat, lng], zoom);
// Used to load and display tile layers on the map
// Most tile servers require attribution, which you can set under `Layer`
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'© OpenStreetMap contributors',
}).addTo(map);
// custom popup image + text
const customPopup = `<div class="customPopup">
<ul class="tabs-example" data-tabs>
<li><a data-tabby-default href="#sukiennice">Sukiennice</a></li>
<li>lorem</li>
</ul>
<div id="sukiennice">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/A-10_Sukiennice_w_Krakowie_Krak%C3%B3w%2C_Rynek_G%C5%82%C3%B3wny_MM.jpg/1920px-A-10_Sukiennice_w_Krakowie_Krak%C3%B3w%2C_Rynek_G%C5%82%C3%B3wny_MM.jpg" width="300">Source: wikipedia.org<div>Kraków,[a] also written in English as Krakow and traditionally known as Cracow, is the second-largest and one of the oldest cities in Poland. Situated on the Vistula River in Lesser Poland Voivodeship... → show more</div>
</div>
<div id="lorem">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut. Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.Lorem ipsum dolor sit amet consectetur, adipisicing elit. Earum, ut.
</div>
</div>`;
// specify popup options
const customOptions = {
minWidth: "220", // set max-width
keepInView: true, // Set it to true if you want to prevent users from panning the popup off of the screen while it is open.
};
const marker = L.marker([50.0616, 19.9373])
.bindPopup(customPopup, customOptions)
.on('click', tabsrun);
marker.addTo(map);
// center map when click on marker
function tabsrun(e) {
if (marker.isPopupOpen()) {
const tabs = new Tabby("[data-tabs]");
}
}
html, body {
height: 100%;
margin: 0;
}
#map {
height: 100%;
}
.tabs-example {
margin-top: -45px !important;
position: absolute;
}
.tabs-example li {
background: #fff;
}
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/tabby#12.0.0/dist/js/tabby.polyfills.min.js"></script>
<link href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/gh/cferdinandi/tabby#12.0.0/dist/css/tabby-ui.min.css" rel="stylesheet"/>
<div id="map"></div>
I have added an example of using a tab to my examples tabs in popup

Append to a string shortened by text-overflow ellipsis

I'd like to cleanly display a string shortened by an ellipsis in quotation marks for example, the string a long sentence that shouldn't be fully displayed shown as "a long sentence...".
However, when I use the ellipsis provided by text-overflow: it will render as "a long sentence... ". What may be done to remove the extra space included in the ellipsis?
Example taken straight from here: text-overflow
I removed the padding on paragraphs. As you can see there is no "extra space"
p {
width: 200px;
border: 1px solid;
padding: 0;
/* BOTH of the following are required for text-overflow */
white-space: nowrap;
overflow: hidden;
}
.overflow-visible {
white-space: initial;
}
.overflow-clip {
text-overflow: clip;
}
.overflow-ellipsis {
text-overflow: ellipsis;
}
.overflow-string {
/* Not supported in most browsers,
see the 'Browser compatibility' section below */
text-overflow: " [..]";
}
<p class="overflow-visible">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p class="overflow-clip">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p class="overflow-ellipsis">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p class="overflow-string">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>

Setting width of <div> to be one of two values based on text content

Is there any way to set width of a <div> using a conditional operator on the size of text within it?
For example, if there are 60 characters or less, width should be 500px else, 700px.
This works fine upto some extent:
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-container > div {
display:block;
min-width: 600px;
margin: 2px;
text-align: left;
}
<div class="flex-container">
<div>(A) Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
</div>
<div>(B) Lorem ipsum dolor sit amet,</div>
<div>(C) Lorem ipsum dolor sit amet </div>
<div>(D) Lorem ipsum dolor sit amet </div>
</div>
Output:
But, when I increase the number of characters of the first child <div>, I get this:
I want all the container elements to shift down once an element crosses a specific character limit, say, 60 characters.
EDIT:
What I wanted is this:
(image)
You could more easily do this with CSS Grid than with flexbox layout; here we take advantage of the minmax() function to determine the column width (bearing in mind we're explicitly styling the whole column, not just the specific 'cell' of content):
grid-template-columns: repeat(2, minmax(min-content, 700px));
Here we use the repeat() function to create two columns, each column assigned a minimum width of 500px or a maximum width of 700px.
This gives the following output:
.flex-container {
display: grid;
grid-template-columns: repeat(2, minmax(500px, 700px));
grid-template-rows: repeat(2, 1fr);
}
.flex-container>div {
white-space: nowrap;
overflow: hidden;
}
<div class="flex-container">
<div>(A) Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
</div>
<div>(B) Lorem ipsum dolor sit amet,</div>
<div>(C) Lorem ipsum dolor sit amet </div>
<div>(D) Lorem ipsum dolor sit amet </div>
</div>
References:
minmax().
repeat().
"Basic concepts of grid layout."
You can do this with jQuery. Run a loop and check all the element, and if one of the element has more than 60 character you apply a width to all of them.
var elem = $('.flex-container > div');
for (var i = 0; i < elem.length; i++) {
if (elem.eq(i).text().length > 60) {
elem.css('width', '600px');
break;
}
}
.flex-container {
display: flex;
flex-wrap: wrap;
}
.flex-container>div {
display: block;
min-width: 300px;
margin: 2px;
text-align: left;
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex-container">
<div>(A) Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
</div>
<div>(B) Lorem ipsum dolor sit amet,</div>
<div>(C) Lorem ipsum dolor sit amet </div>
<div>(D) Lorem ips </div>
</div>
You can resolve this with JavaScript, using the string length property and a condition.
1) Create a variable in JavaScript to access the div you created using : document.getElementsByTagName("div").innerHTML;
2) Use the if. In the condition use the length property and a compactor to see if the length is bigger then a certain number of characters.
3) In the statements add document.getElementsByTagName("div").style.width = x; and modify the width by the number you want by changing x.
Using a conditional operator, you've set the size of a div depending on the size of text.

Remove CSS class properties for Child List Items

I've been trying to create an unordered List in Html.
A css class will be attached with the "ul" element and its child "li" elements.
The issue is if another "unordered List" becomes child element of this parent unordered List.
I've created following sample to show my issue:-
Javascript:-
$(function () {
$('.marquee').marquee({
duration: 10000,
duplicate: false,
delayBeforeStart:0,
allowCss3Support: true,
gap: 600,
});
});
HTML:-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.marquee/1.3.1/jquery.marquee.min.js"></script>
<ul class='marquee'>
<li>1. Longer text lorem ipsum dolor sit amet,<h3>consectetur adipiscing elit END</h3></li>
<li>2. Longer text lorem ipsum dolor sit amet, consectetur adipiscing elit END</li>
<li>3. Longer text lorem ipsum dolor sit amet, consectetur adipiscing elit END</li>
<li>4. Longer text lorem ipsum dolor sit amet, consectetur adipiscing elit END</li>
<li><ul><li><b>I'm the Child Unordered List Element. I don't want this CSS</b></li></ul></li>
</ul>
CSS:-
body {
margin: 10px;
font-family:'Lato', sans-serif;
}
.marquee {
width: 100%;
overflow: hidden;
border:1px solid #ccc;
background: black;
color: rgb(202, 255, 195);
}
ul.marquee li {
display: inline-block;
padding: 10px 20px;
}
Jsfiddle
Can any one suggest how to remove the CSS class "marquee" from the Child Unordered List?
Thanks in advance.
Please share the code in your question. For now which i understood by your statement, that can be achieved by using below code (replace '.xyz' with actual class)
jQuery("ul.xyz").find("ul.xyz").removeClass(".xyz");
I've noticed your ul within the parent ul is not within a li. Make sure any child element in a list is within a li element.

Center button and text issues HTML

I am trying to make a onClick() button that when pressed, makes text show. My issue is that when I click the button, the button scoots down when the text shows up.
Is there a way to make the button not move when the text appears? Maybe make it actually be there but hidden and on button unhide it? I don't know, I just don't want it to move when the button is pressed.
angular.module('starter.controllers', ['ionic'])
.controller('HomeCtrl', function($scope) {
$scope.flip = function() {
$scope.coinResult = "Heads";
}
})
<body ng-app="starter">
<head>
<style>
.button-calm {
width: 50%;
}
.coin-result {
text-align: center;
line-height: 100px;
}
.centerItems {
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<ion-content>
<div class="centerItems">
<p class="coin-result" ng-bind="coinResult"></p>
<button class="button button-outline button-calm" ng-click="flip()">Flip!</button>
</div>
</ion-content>
</body>
One way would be to fix the height of the text div coin-result and give it overflow-y: auto. This ensures that the button stays put.
Demo below:
.button-calm {
width: 50%;
}
.coin-result {
text-align: center;
line-height: 100px;
height: 100px;
overflow-y: auto;
}
.centerItems {
margin-left: auto;
margin-right: auto;
}
<div class="centerItems">
<p class="coin-result" ng-bind="coinResult">Lorem ipsum dolor sit amet, consectetur adipisicing elit<br/>Lorem ipsum dolor sit amet, consectetur adipisicing elit<br/>Lorem ipsum dolor sit amet, consectetur adipisicing elit<br/>Lorem ipsum dolor sit amet, consectetur adipisicing elit<br/>Lorem ipsum dolor sit amet, consectetur adipisicing elit<br/>Lorem ipsum dolor sit amet, consectetur adipisicing elit<br/>Lorem ipsum dolor sit amet, consectetur adipisicing elit</p>
<button class="button button-outline button-calm" ng-click="flip()">Flip!</button>
</div>
Let me know your feedback on this. Thanks!

Categories

Resources