I have a webpage with the following HTML:
<div class="panel panel-primary" style="width:auto;height:auto;">
<div class="panel-heading" id="ContentHeader" runat="server" style="width:auto;height:auto;">Table</div>
<div class="panel-body" runat="server" style="width:auto;height:auto;">
<div class="table-responsive">
<asp:GridView ID="ExcelContentView" runat="server" class="table table-bordered" >
<HeaderStyle CssClass="info" />
</asp:GridView>
</div>
</div>
</div>
i reference this pages answer.
it works fine only with overflow-x.
however, scroll bar is broken when overflow-x with overflow-y case.
About 53 rows and 15 columns:
vertical scrollbar is not working.
but Left Or Right Key is move scrollbar.
clicking scrollbar is broken i think.
how do i fix scroll bar in overflow x and y case?
here is additional c# code behind
on page load :
{
ExcelContentView.DataSource = ExcelViewManager.Instance.GetExcelViewTable(fileName, historyNum);
ExcelContentView.DataBind();
} // method
and GetExcelViewTable Method
{
DataTable stringTable = new DataTable();
var currType = GameDataFileManager.Instance.GetTypeFromFileName(fileName);
string historyPath = GameDataFileManager.Instance.GetHistoryPathByType(currType);
string fullPath = historyPath + fileName + revNum + ".xlsx";
FileInfo excelFileInfo = new FileInfo(fullPath);
ExcelPackage excel = new ExcelPackage(excelFileInfo);
var workSheet1 = excel.Workbook.Worksheets.First();
int colCount = 0;
//
for (int iCol = 1; iCol <= workSheet1.Dimension.End.Column; ++iCol )
{
stringTable.Columns.Add( workSheet1.Cells[1, iCol].Text, typeof(string) );
++colCount;
} // for
for (int iRow = 3; iRow <= workSheet1.Dimension.End.Row; ++iRow )
{
List<object> objList = new List<object>();
for (int iCol = 1; iCol <= workSheet1.Dimension.End.Column; ++iCol )
{
objList.Add( workSheet1.Cells[iRow, iCol].Text );
} // for
int objCount = objList.Count;
if (colCount != objCount)
{
DotNetMsgBox.Show("Debug");
}
stringTable.Rows.Add(objList.ToArray());
} // for
return stringTable;
}
I solved this.
table-responsive is broken scrollbar when using with simple sidebar
responsive broken when this code.
<li class="sidebar-footer">Made by Me</li>
so, this sidebar-footer code makes problem.
i dont know why this code broken table-responisve sidebar.
i open simple-sidbar.css, and see this codes
.sidebar-nav > .sidebar-footer {
display: block;
text-decoration: none;
color: #fff;
position: fixed;
height: 100px;
bottom: 0;
width: 100%;
}
and i delete code in { }, but still has problem.
so, i delete sidebar-footer in my Master Page. and yes. i solved problem.
anyone tell me why this sidebar-footer broken scrollbar.
Related
I have a carousel where an arbitrary number of images can be shown.
It currently looks like below, where the problem is that the amount carousel indicators quickly gets out of hand.
I want to try to do something similar to how Airbnb has it, where it only shows a maximum of 5 dots at any given time. I found an example of an implementation of this on codesandbox, but I'm using Blazor and not React, making it kind of hard to directly translate it.
To show what I'm talking about, their carousel looks like this
My current implementation in Blazor looks like his
<span class="progress-dots">
#for (int i = 0; i < Imgs.Count; i++)
{
<span class='progress-dot #( currentImage == i ? "active" : "")'></span>
}
</span>
where currentImage is just tracking the index of the active image. This just couples with some simple css to show which one is active.
.progress-dots {
position: absolute;
bottom: 5px;
left: 5px;
right: 5px;
display: flex;
justify-content: center;
span.progress-dot {
width: 0.45rem;
height: 0.45rem;
border-radius: 50%;
background: rgba(174, 174, 174, 0.453);
margin: 0.2rem 0.15rem;
&.active {
background: #FFF;
}
}
}
Here is a Blazor repl with a stripped down version of my own implementation to test how it works.
You want to take into account the edge cases. The solution I am giving can probably be improved or cleaner, I just focused on a working example.
<div class="img-container">
<span class="progress-dots">
#{
int imgIncMin = 0;
int imgIncMax = Imgs.Count;
int dotsDisplayed = DotsDisplayedAround * 2 + 1;
if(Imgs.Count > dotsDisplayed){
if(currentImage < DotsDisplayedAround){
imgIncMin = 0;
imgIncMax = dotsDisplayed;
}
else if(currentImage + DotsDisplayedAround >= Imgs.Count){
imgIncMin = Imgs.Count - dotsDisplayed;
imgIncMax = Imgs.Count;
}
else{
imgIncMin = currentImage - DotsDisplayedAround;
imgIncMax = currentImage + DotsDisplayedAround + 1;
}
}
}
#for (int i = imgIncMin; i < imgIncMax; i++)
{
<span class='progress-dot #( currentImage == i ? "active" : "")'></span>
}
</span>
</div>
<div class="btn btn-dark" #onclick='() => { currentImage = currentImage - 1 >= 0 ? currentImage - 1 : Imgs.Count - 1 ; }'>Previous</div>
<div class="btn btn-dark" #onclick='() => { currentImage = (currentImage + 1) % Imgs.Count; }'>Next</div>
#code {
const int DotsDisplayedAround = 2;
int currentImage = 0;
List<string> Imgs = new List<string>() { "", "", "", "", "", "", ""};
}
Blazor repl
Is there a way to create an multiple row image slider like the one in the image below using just css? or is there a way to do this with angular?
The slider needs to move as one (single rows cannot be swiped individually).
First you need to understand the overflow property in css:
https://css-tricks.com/almanac/properties/o/overflow/
This will allow you to see there is a scroll property. That can make your scroll bars. Yours should use overflow-x to scroll the direction you want it to go.
As for angular, you need to look into ng-repeat command. Here is a fiddle that is doing what you are looking for:
<div ng-repeat="user in users | limitTo:display_limit">
http://jsfiddle.net/bmleite/hp4w7/
Quick answer to your question.. no, there is no way to do this with just CSS because you will have to handle the swipe, touch, click, etc. events using javascript. I guess I was working under the assumption that you would be adding angularjs into your application solely for this purpose, so I made a jQuery solution. If that is a wrong assumption, I will rewrite an angular solution.
Basically, the idea is that you structure your HTML/CSS in a way to get the effect of the sliding within a given container, and then use event handlers to update the slider as the user interacts with it.
Working DEMO
HTML
<div class="slider-display centered">
<div class="image-container">
<div class="image">Image<br>1</div>
<div class="image">Image<br>2</div>
<div class="image">Image<br>3</div>
<div class="image">Image<br>4</div>
<div class="image">Image<br>5</div>
<div class="image">Image<br>6</div>
<div class="image">Image<br>7</div>
<div class="image">Image<br>8</div>
<div class="image">Image<br>9</div>
<div class="image">Image<br>10</div>
<div class="image">Image<br>11</div>
<div class="image">Image<br>12</div>
<div class="image">Image<br>13</div>
<div class="image">Image<br>14</div>
<div class="image">Image<br>15</div>
<div class="image">Image<br>16</div>
<div class="image">Image<br>17</div>
<div class="image">Image<br>18</div>
</div>
</div>
<div class="centered" style="text-align: center; max-width: 350px;">
<button class="move-left"><--</button>
<button class="move-right">--></button>
</div>
Javascript
$(function () {
var getWidth = function ($element) {
var total = 0;
total += $element.width();
total += Number($element.css("padding-left").replace("px", ""));
total += Number($element.css("padding-right").replace("px", ""));
total += Number($element.css("border-left").split("px")[0]);
total += Number($element.css("border-right").split("px")[0]);
total += Number($element.css("margin-left").split("px")[0]);
total += Number($element.css("margin-right").split("px")[0]);
return total;
};
var sliderPosition = 0;
var imageWidth = getWidth($(".image").eq(0));
$(".move-left").on("click.slider", function () {
var maxVisibleItems = Math.ceil($(".slider-display").width() / imageWidth);
var maxItemsPerRow = Math.ceil($(".image-container").width() / imageWidth);
var numRows = Math.ceil($(".image-container .image").length / maxItemsPerRow);
var maxPosition = numRows > 1 ? maxVisibleItems - maxItemsPerRow : maxVisibleItems - $(".image-container .image").length;
if (sliderPosition > (maxPosition)) {
sliderPosition--;
var $imageContainer = $(".image-container");
$(".image-container").animate({
"margin-left": sliderPosition * imageWidth
},{
duration: 200,
easing: "linear",
queue: true,
start: function () {
$(".move-left").prop("disabled", true);
},
done: function () {
$(".move-left").prop("disabled", false);
}
});
}
});
$(".move-right").on("click.slider", function () {
if (sliderPosition < 0) {
sliderPosition++;
var $imageContainer = $(".image-container");
$(".image-container").animate({
"margin-left": sliderPosition * imageWidth
},{
duration: 200,
easing: "linear",
queue: true,
start: function () {
$(".move-right").prop("disabled", true);
},
done: function () {
$(".move-right").prop("disabled", false);
}
});
}
});
});
CSS
.image {
float: left;
height: 80px;
width: 80px;
background: #888888;
text-align: center;
padding: 5px;
margin: 5px;
font-size: 1.5rem;
}
.image-container {
width: 650px;
position: relative;
}
.slider-display {
max-width: 450px;
overflow: hidden;
background: #ddd
}
.centered {
margin: 0 auto;
}
I want to create category list with sub category. The sub category will open when user clicks on the parent category. This is like a multi level menu tree.
The functionality works fine, but the style for the child nodes is not applying. The reason is that I create the sub menu dynamically and I cannot set the style rules.
Here is my code:
<template>
<div id="cat_menu">
<!--<category-service id="service" categories="{{categories}}"></category-service>-->
<iron-ajax id="ajax"
auto
url="../api/index.php"
method="POST"
last-response="{{categories}}"
params='{"tag":"get_cat_list"}'
handleAs="json">
</iron-ajax>
<template is="dom-repeat" items="{{categories.cat_list}}" filter="getParent" id="t">
<paper-fab mini id="fab_{{item.category_id}}" icon="edit" class="p_fab"></paper-fab>
<paper-menu id="{{item.category_id}}" class="cat_item" on-click="selectAction">
<span >{{item.category_name}}</span>
</paper-menu>
</template>
<div>
</template>
selectAction: function (e, detail) {
var str = '';
if (detail) {
var selectedItem = e.currentTarget;
//Polymer.dom(selectedItem).childNodes[1].innerHTML = '';
for (var i = 0; i < this.categories.cat_list.length; i++) {
//var item = new Object;
var item = this.categories.cat_list[i];
if (selectedItem.id == item.parent_id) {
var container = document.createDocumentFragment();
var paper_submenu = document.createElement('paper-menu');
paper_submenu.id = item.category_id;
paper_submenu.innerText = item.category_name;
paper_submenu.className = 'cat_item';
//paper_submenu.classList.add('cat_item');
paper_submenu.onclick = 'selectAction';
Polymer.dom(selectedItem.childNodes[1]).appendChild(paper_submenu);
Polymer.updateStyles();
}
}
}
}
CSS Style:
.cat_item {
border: 1px solid #acdcd8;
margin: 5px;
background-color: rgb(255, 255, 255);
padding-left: 10px;
}
The element cannot see this class cat-item. Can someone please help me solve this?
How can i position my dropdown at cursor position inside a textarea? I have found this question was already asked here many times but i cant able figure out the correct solution ..
this is the JSBIN
please help me with your suggestions
Thanks in advance
I know it isn't an exact answer on the question (this solution doesn't use a textarea, but a contentEditable div), but I don't think there is any way of getting x-y-coordinates using either the event, an attribute or function on the textarea or an attribute or function on the Selection object.
I have meshed up an example on JSBin. Please note that I haven't bothered testing for compatibility in other browsers and that it won't return the caret to where you left off. I can't figure out the code for that. I believe window.getSelection() will not work in IE, and in IE8- it would be completely different. You probably want to make sure too, that the menu will not be displayed right from the edge of the screen.
The HTML
<div id="target" contentEditable="true">Type # to see the dropdown.... </div>
<div class="dropdown">
<ul id="dropdown" class="dropdown-menu hide" role="menu" aria-labelledby="dropdownMenu">
<li><a>One</a> </li>
<li><a>Two</a></li>
<li><a>Three</a></li>
<li><a>Four</a> </li>
</ul>
</div>
The CSS
#target {
height: 100px;
border: 1px solid black;
margin-top: 50px;
}
#dummy {
display: inline-block;
}
.dropdown {
position: absolute;
top: 0;
left: 0;
}
The Javascript & JQuery
$("#target").keydown( function(e) {
if(e.which === 50 && e.shiftKey === true ) {
//Prevent this event from actually typing the #
e.preventDefault();
//console.log( window.getSelection() );
var sel = window.getSelection();
var offset = sel.baseOffset;
var node = sel.focusNode.parentNode;
//Get the text before and after the caret
var firsttext = node.innerHTML.substr(0,sel.baseOffset);
var nexttext = (sel.baseOffset != sel.focusNode.length ) ? node.innerHTML.substr( sel.baseOffset, sel.focusNode.length) : "";
//Add in # + dummy, because # is not in there yet on keydown
node.innerHTML = firsttext + '#<div id="dummy"></div>' + nexttext;
//Transfer all relevant data to the dropdown menu
$('.dropdown').css('left', $('#dummy')[0].offsetLeft).css('top', $('#dummy')[0].offsetTop).prop('x-custom-offset', offset + 1);
//Delete the dummy to keep it clean
//This will split the contents into two text nodes, which we don't want
//$('#dummy').remove();
node.innerHTML = firsttext + '#' + nexttext;
//Put the caret back in place where we left off
//...I can't seem to figure out how to correctly set the range correctly...
$('#dropdown').removeClass('hide').addClass('show');
} else {
$('#dropdown').removeClass('show').addClass('hide');
$('.dropdown').removeProp('x-custom-offset');
}
});
$('#dropdown').on( 'click', 'li a', function( e ) {
e.preventDefault();
$('#target').html( function( i, oldtext ) {
var firsttext = oldtext.substr( 0, $('.dropdown').prop('x-custom-offset') );
var nexttext = oldtext.substr( $('.dropdown').prop('x-custom-offset'), oldtext.length );
console.log( e );
var inserttext = e.target.innerText;
//Cleanup
$('#dropdown').removeClass('show').addClass('hide');
return firsttext + inserttext + nexttext;
} );
} );
The explanation
This example works based on that you can insert an element in a contentEditable and retrieve it's offset to the top and the left of the screen. When shift + key 50 is pressed, the event handler will prevent the # from being written and instead inserts the # + dummy object itself. Then we retrieve the offset from this object and move the dropdown menu to that offset. Furthermore, we save the character-offset as a custom property x-custom-offset of the menu, so that we can insert a value at that specific location. We then need to remove the dummy div, but if we would remove the dummy with $('#dummy').remove() the text node before the dummy and the text node behind the dummy will not merge. This will delete the last textnode if we were to put an other # somewhere and/or place it in the wrong location. Therefore, we simply replace the contents of the editable div again. Last, the caret must be set back to it's original position. I cannot figure out how to do this properly though.
The second handler is to insert text into the textbox. The code should be self-explanatory. The x-custom-offset property we set earlier is used here to insert the text into the correct place in the textbox. $('#dropdown').on( 'click', 'li a', function( e ) { ... } ); will attach the click event to the ul instead of the li's, so that it will keep working if you dynamically create the li's (but it will only fire if you click the link part).
You can get the position of the mouse and then move the drop-down list to this position.
You just need to ensure the popup content has a higher z-index than the element you'd like it occlude, and that it's position is set to absolute.
Here's a small test sample I wrote once.
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function toggleClass(element, newStr)
{
index=element.className.indexOf(newStr);
if ( index == -1)
element.className += ' '+newStr;
else
{
if (index != 0)
newStr = ' '+newStr;
element.className = element.className.replace(newStr, '');
}
}
function forEachNode(nodeList, func)
{
var i, n = nodeList.length;
for (i=0; i<n; i++)
{
func(nodeList[i], i, nodeList);
}
}
window.addEventListener('load', mInit, false);
function mInit()
{
}
function onShowBtn(e)
{
var element = byId('popup');
element.className = element.className.replace(' hidden', '');
var str = '';//'border-radius: 32px; border: solid 5px;';
e = e||event;
str += "left: " + e.pageX + "px; top:"+e.pageY+"px;"
element.setAttribute('style',str);
}
function onHideBtn()
{
var element = byId('popup');
if (element.className.indexOf(' hidden') == -1)
element.className += ' hidden';
}
</script>
<style>
#controls
{
display: inline-block;
padding: 16px;
border-radius: 6px;
border: solid 1px #555;
background: #AAA;
}
#popup
{
border: solid 1px #777;
border-radius: 4px;
padding: 12px;
background: #DDD;
display: inline-block;
z-index: 2;
position: absolute;
}
#popup.hidden
{
visibility: hidden;
}
</style>
</head>
<body>
<div id='controls'>
<input type='button' value='show' onclick='onShowBtn()'>
<input type='button' value='hide' onclick='onHideBtn()'>
</div>
<br>
<div id='popup'>
<p>This is some assorted
text</p>
<hr>
<ul>
<li>item a</li>
<li>item 2</li>
<li>item iii</li>
</ul>
</div>
</body>
</html>
I have two CSS classes:
.class1 {
height: 100%;
width: 300px;
border: 1px none #B0B0B0;
position: relative;
display: inline;
left: 10px;
}
.class2 {
height: 100%;
width: 200px;
position: relative;
display: inline;
margin-left: 15px;
background-color: #00CCCC;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
}
Now, as you can see, they're both set to display in a line (no line breaks in between elements). Which works correctly. But for some reason, ever since I set the display to inline, the Padding, the Positioning and the Margin CSS have all just stopped working. I can add a margin-left 10inches and nothing will happen. Same with padding and positioning.
Can anyone explain how to fix this?
Also, I have the relative position set on both classes, yet when viewing the page in a browser, .class2 over laps .class1 when its supposed to be just after .class1.
Any ideas?
EDIT:
Okay, so I've done a JSFiddle, but it seems to be playing up even more there....
Looks like the Width is not working....
here it is:
http://jsfiddle.net/zYbwh/1/
You need to use
display: inline-block;
instead. margin doesn't work with display: inline elements, however with inline-block it does. You can then have an inline element with margins and explicit widths/heights.
To make this work in IE7, add these two lines:
*display: inline;
zoom: 1;
It's horrible, but it works.
I know this is quite a late answer but I wrote a jQuery plugin which support padding on inline elements (with word breaking) see this JSfiddle:
http://jsfiddle.net/RxKek/
Plugin Code:
$.fn.outerHTML = function () {
// IE, Chrome & Safari will comply with the non-standard outerHTML, all others (FF) will have a fall-back for cloning
return (!this.length) ? this : (this[0].outerHTML || (
function (el) {
var div = document.createElement('div');
div.appendChild(el.cloneNode(true));
var contents = div.innerHTML;
div = null;
return contents;
})(this[0]));
};
/*
Requirements:
1. The container must NOT have a width!
2. The element needs to be formatted like this:
<div>text</div>
in stead of this:
<div>
text
</div>
*/
$.fn.fixInlineText = function (opt) {
return this.each(function () {
//First get the container width
var maxWidth = opt.width;
//Then get the width of the inline element
//To calculate the correct width the element needs to
//be 100% visible that's why we make it absolute first.
//We also do this to the container.
$(this).css("position", "absolute");
$(this).parent().css("position", "absolute").css("width", "200%");
var width = $(this).width();
$(this).css("position", "");
$(this).parent().css("position", "").css("width", "");
//Don't do anything if it fits
if (width < maxWidth) {
return;
}
//Check how many times the container fits within the box
var times = Math.ceil(width / maxWidth);
//Function for cleaning chunks
var cleanChunk = function (chunk) {
var thisChunkLength = chunk.length - 1;
if (chunk[0] == " ") chunk = chunk.substring(1);
if (chunk[thisChunkLength] == " ") chunk = chunk.substring(0, thisChunkLength);
return chunk;
};
//Divide the text into chunks
var text = $(this).html();
var textArr = text.split(" ");
var chunkLength = Math.ceil((textArr.length - 1) / times);
var chunks = [];
var curChunk = "";
var curChunkCount = 0;
var isParsingHtml = false;
//Loop through the text array and split it into chunks
for (var i in textArr) {
//When we are parsing HTML we don't want to count the
//spaces since the user doesn't see it.
if (isParsingHtml) {
//Check for a HTML end tag
if (/<\/[a-zA-Z]*>/.test(textArr[i]) || /[a-zA-Z]*>/.test(textArr[i])) {
isParsingHtml = false;
}
} else {
//Check for a HTML begin tag
if (/<[a-zA-Z]*/.test(textArr[i])) {
isParsingHtml = true;
}
}
//Calculate chunks
if (curChunkCount == (chunkLength - 1) && !isParsingHtml) {
curChunk += textArr[i] + " ";
chunks.push(cleanChunk(curChunk));
curChunk = "";
curChunkCount = -1;
} else if ((i == (textArr.length - 1))) {
curChunk += textArr[i];
chunks.push(cleanChunk(curChunk));
break;
} else {
curChunk += textArr[i] + " ";
}
if (!isParsingHtml) {
curChunkCount++;
}
}
//Convert chunks to new elements
var el = $($(this).html("").outerHTML());
for (var x in chunks) {
var new_el = el.clone().html(chunks[x]).addClass("text-render-el");
var new_el_container = $("<div/>").addClass("text-render-container");
new_el_container.append(new_el);
$(this).before(new_el_container);
}
//Finally remove the current element
$(this).remove();
});
};
Thats the problem you get when using templates, ive programmed a site in php, but the design is killing me.
So i try'd some rocket fuel for webdesigners.
And this is the problems i keep getting every step of the way...
Inline-block does not work for me, nothing works, becouse it is not my design and i dont know the setup.
Ive tryd doing the design myself, but i am out of time, i need a design yesterday.
I suggest you take what u need from the templates and delete everything else, that will schrink your problem, and save you time.