I have a page with a set of drop-downs. Changing those drop-downs generates a small snippet of code corresponding to the selection.
The sample below is a how all bindings have been written at the moment.
jQuery('#one').on('change', function(event){
var selectedElement = $(this).find('option:selected');
jQuery('#code-section').text("You have selected " + selectedElement.text());
});
.code-section {
width: 100px;
height: 50px;
margin-top: 20px;
border: 1px solid red;
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="block" class="block-one">
<select name="one" id="one">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<div class="code-section" id="code-section">
//This is the code snippet area
</div>
</div>
I now have to add another set to the same page. It will behave exactly like the first set but will generate a different kind of snippet.
All the javascript bindings for the 1st set are coupled with element ids. How do I add another dropdown with its own bindings with minimal duplication of code?
Some of the ways I have been trying are:
Move all bindings from ids to classes - The issues with this method is that almost all operations have been done using absolute ids and corresponding attributes of those element. This will require a massive rewrite of all the JS.
Rewrite the Javascript to make it operate on parameters instead of direct bindings - This theoretically would be the right approach but will require a lot of time which is something I cannot afford at the moment.
Duplicate both markup and JS for the dropdown and change all ids in the copy - Not ideal but will the get the job done.
Is there is any other way to look at this?
Related
I'm trying to make a personalized :hover for <option> elements in <select> selector by mouseover eventListener. But for some reasons mouseover does not fired when the mouse has been on the option element.
var selectOne = document.querySelector('.select__first');
var selectTwo = document.querySelector('.select__second');
for (var key in selectOne) {
if (key % 2 == 0)
selectOne[key].classList.add('select__option-blue');
}
for (var key in selectTwo) {
if (key % 2 == 0)
selectTwo[key].classList.add('select__option-blue');
}
function onMouseOver(e) {
var target = event.target;
var options = event.target.closest('option');
if (!options) return;
console.log(options);
}
document.addEventListener( 'mouseover', onMouseOver);
.select__element > p, span {
display: inline-block;
}
.select {
-webkit-appearance: listbox;
cursor: pointer;
}
.select__option-blue {
background-color: lightblue;
}
option {
cursor: pointer;
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
</style>
</head>
<body>
<div class="select-row">
<div class="select__element">
<p>The last element: </p><span class="select__element-last"></span>
</div>
<select class="select select__first">
<option value="birds" hidden>Select an element...</option>
<option value="birds">One</option>
<option value="fishes">Two</option>
<option value="animals">Three</option>
<option value="dino">Four</option>
<option value="simplest">Five</option>
</select>
<select class="select select__second">
<option value="birds" hidden>Select an element...</option>
<option value="ploto">One</option>
<option value="trava">Two</option>
<option value="vseyad">Three</option>
</select>
</div>
<script>
</script>
</body>
</html>
Apparently, Chrome doesn't support mouse events on option elements, unless you specify the size attribute to the select element.
Mouse over option in select tag
jQuery-Select list option hover
onMouseMove doesn't fire over <option> element in Chrome
So, yes, the situation around option is a very sad. :(... As say #Veehmot - we cannot bind mouseevents on option elements of selector select normaly in pure JS.
But! In view of the fact that I did not find any clear information on stackoverflow about what exactly can be done to stylize options and select selector on pure JavaScript, I want to share my success in this direction and give the community 2 ways of solving this problem based on pure JavaScript.
I found a really two working ways for coders, who also like me will face the necessity of styling option and select on pure JavaScript without the use of frameworks (jQuery, etc.)
The first way (not direct and harder) is to make the select element with options in the form of <div> selector with <buttons> or <li> list inside. The introdusing of how it work you can see on my CodePen project-page below:
https://codepen.io/Sviatoslav_FrontEnd/pen/PQbBYQ
The second way is to connect one interesting JS library, created for options and select styling. This is really what we want, and it base on pure JavaScript with CSS. BUT! I want to admit, that this script is not mine. I found it on the open-source blog resource. So I'm not responsible for its support or help in setting up. All at your own peril and risk.
I place here a link to this JS library and support files solely to help the same as I - lovers a pure javascript.
Link: https://di-grand.com/blog?download=1&kccpid=3338&kcccount=https://di-grand.com/blog/wp-content/uploads/2016/10/select.rar
I am using select and ng-options in angularjs to show a list of years that I construct myself. I pass the current year as the default value to the select.
here is the plunker link.
My question is:
How to center the list on the default value?
My plunker is not complete because my real situation is like the one found here
http://www.cliptheme.com/demo/clip-two/AngularJs-Admin/STANDARD/#/app/form/wizard
Go to Forms / Form Wizard / Step 3 Billings
as you can see, by choosing a year, and then clicking back again on it, the menu is centered on that selected year.
But my problem is that when I pass the default year value to it, as if I have already selected, and then I click back on the list, I should see it centered on that default value, but it isn't. Once I click again on that year, and click on the list again, I see it centered.
In other words, passing a year as default value doesn't play the same role as if I selected it for the first time by clicking, because when I re-click again, it is not centered. How can we fix this problem?
Here is the CSS file for the selecter I am using: css link, this is not included in the plunker nor in the snippet, because I couldn't properly reproduce that CSS on the plunker, if you can, please do it.
var app = angular.module('app', []);
app.controller('MyCtrl', function($scope) {
$scope.dates = {};
$scope.years = [{value: 'Year', disabled: true}];
var current_year = new Date().getFullYear();
for(var i = current_year - 20; i <= current_year + 20; i++){
$scope.years.push({value: i + ''});
}
var d = new Date();
var n = d.getFullYear();
$scope.dates.startYear = n;
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="MyCtrl">
<label class="control-label">Year</label>
<select name="startYear" ng-model="dates.startYear" id="startYear"
ng-options="year.value as year.value disable when year.disabled for year in years"
required>
<option value="" disabled >Choose one</option>
</select>
</div>
</body>
update 1:
Here is the directive that handles this particular element:
https://pastebin.com/0diFfH6t
update 2:
Here is the plunker that shows exactly the problem even after Dekel's solution.
https://plnkr.co/edit/aWbZkp4xitvBcMmhHadI?p=preview
as you can see, on the page load, when clicked on the dropdown menu, it doesn't center on the default value.
First I gotta say that the <select> tag is not a standard tag, since the rendering of that tag is partially done by the OS and not the browser, so it behaves a little different then other elements, and you can't really apply css to everything you need there.
Having said that - there are (almost) always hacks that can be done, and I'm going to show this example as one of the hacks:
function selectfocus() {
el = event.target;
sizeWhenOpen = 5;
el.size=sizeWhenOpen;
totalHeight = el.getBoundingClientRect().height;
heightPerOption = el.scrollHeight/el.options.length;
currentIndex = el.selectedIndex;
el.scrollTop = heightPerOption * (currentIndex - Math.floor(sizeWhenOpen/2));
}
<select
onfocus="selectfocus()"
onblur="this.size=1;"
onchange="this.size=1; this.blur();">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
<option>11</option>
<option>12</option>
<option>13</option>
<option>14</option>
<option>15</option>
<option>16</option>
<option>17</option>
<option>18</option>
<option>19</option>
<option>20</option>
<option>21</option>
</select>
Since we can't control the number of elements that will be displayed when the <select> is open, i used two states - one when closed (size=0) and one when open (size=5 in the example). When the select is open - I took the current selected option (based on the index) and scrolled the select to the relevant position do make sure it's centered.
Another important note - inside your application you might need use css to position (absolute/relative) the select/it's container in order to keep the original size (the size when open is bigger than the size when closed).
And here is the angular version, based on your plunkr:
https://plnkr.co/edit/eV1sPxENpcO1xXcS6JL3?p=preview
Final note - If you need exact things from the <select> tag in your website - use an implementation of drop-down that is based on regular html elements and not select :)
Why not just write some CSS to target the span tag?
span { text-align: center; }
or better yet.... tag it to an id or class
.className { text-align: center; }
#idName { text-align: center; }
Below is a functional plunker.
Plunker Example
With reference to your Update 2 plunk link you just need to update your CSS. Specify the width(whatever you want) of your area in which you have to place the select box. This will surely fix your problem :)
.myctrl {
position: absolute;
vertical-align: top;
margin-left: 50px;
width: 200px;
}
The thing is that your example on cliptheme.com does not scroll at all. It just stays centered because the div keeps it scroll position.
So to solve your issue you just need to calculate the right position and set it to the .cs-options div. One event which could be used is _toggleSelect.
Working example (see line 370-372):
https://plnkr.co/edit/XgoeU8igSSeu044EFBCV
This is just a hint and your final solution should be more sophisticated (like not query the elements every time the list is opened).
You can apply styling to id of select box as below
<!DOCTYPE html>
<html ng-app="app">
<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<script src="script.js"></script>
</head>
<style>
#startYear{
padding:0 1% 0 10%;
}
</style>
<body>
<div ng-controller="MyCtrl">
<label class="control-label">Year</label>
<select name="startYear" ng-model="dates.startYear" id="startYear"
ng-options="year.value as year.value disable when year.disabled for year in years"
required>
<option value="" disabled >Choose one</option>
</select>
</div>
</body>
</html>
I have a div that contains text that is selected dynamically using a drop down menu. When my page loads the text shows before disappearing once the page has fully loaded. Is there any way of stopping this happening? As i only want the text to appear once it has been selected.
HTML :
<select id="selectMe">
<option value="option1">option1</option>
<option value="option2">option2</option>
<option value="option3">option3</option>
<option value="option4">option4</option> </select>
<div class="group" id="option1">asdf</div>
<div class="group" id="option2">Tilt.</div>
<div class="group" id="option3">zxcv</div>
<div class="group" id="option4">qwerty</div>
Jquery:
(function($) {
$(document).ready(function () {
$('.group').hide();
$('#option1').show();
$('#selectMe').change(function () {
$('.group').hide();
$('#'+$(this).val()).show();
})
})
})(jQuery);
It has to be hidden BEFORE your code runs. Use CSS:
.group { display: none }
Simply hide them by default:
.group {
display: none;
}
Or, if you need them to still occupy block space (to prevent page "jumps"):
.group {
visibility: hidden;
}
There is an another way round with JavaScript like this:-
document.getElementById("option1").innerHTML="asdf";
By using this you can keep the div(where the text is to be shown) empty in the starting so that there will be no chance of text being displayed before it is needed, and when a user clicks on the options then JS will just add this text to the div!
You may use innerhtml to introduce the display:none rule to avoid to hide it even if jQuery/javascript is not avalaible .
basicly, in your head right before the body tag you can do this :
<script>
var el=document.body;
el.innerHTML = "<style>.group {display: none;}</style>";
</script>
It will hide the .group elements untill jQuery is loaded and effective.
If , for some reason javaScript is not avalaible, nothing will be hidden.
You can play with it here : http://codepen.io/anon/pen/khbnp
Version with jQuery removed http://codepen.io/anon/pen/tjraw
Version without jQuery nor javaScript http://codepen.io/anon/pen/disut actually shows what's hidden by previous version
I got this site designed already by front end designers. All select boxes are restyled when the page run in a browser. The problem is I want to show the previously selected value but I dont know how to do that if I cant assign a unique id to the modified select. Here is the modified drop down html:
<div unselectable="on" style="-webkit-user-select: none; -webkit-tap-highlight-color:
rgba(255, 255, 255, 0); width: 66px; " class=" select-area select-modify_select
select-focus ">
<span class="left"></span>
<span class="center">B.N.S.</span>
<a class="select-opener"></a>
</div>
<select name="ach_bank" id="ach_bank" class="modify_select jcf-hidden"
style="-webkit-tap-highlight-color: rgba(255, 255, 255, 0); ">
<option value="">Select...</option>
<option value="B.N.S.">B.N.S.</option>
<option value="F.G.B.">F.G.B.</option>
<option value="N.C.B.">N.C.B.</option>
<option value="R.B.C.">R.B.C.</option>
</select>
As you can see the regular select box is hidden and a modified drop down is created. The code that modified the select box is here:
// custom select module
jcf.addModule({
name:'select',
selector:'select',
defaultOptions: {
handleDropPosition: true,
wrapperClass:'select-area',
focusClass:'select-focus',
dropActiveClass:'select-active',
selectedClass:'item-selected',
disabledClass:'select-disabled',
valueSelector:'span.center',
optGroupClass:'optgroup',
openerSelector:'a.select-opener',
selectStructure:'<span class="left"></span><span class="center"></span>
<a class="select-opener"></a>',
selectPrefixClass:'select-',
dropMaxHeight: 200,
dropFlippedClass: 'select-options-flipped',
dropHiddenClass:'options-hidden',
dropScrollableClass:'options-overflow',
dropClass:'select-options',
dropClassPrefix:'drop-',
dropStructure:'<div class="drop-holder"><div class="drop-list">
</div></div>',
dropSelector:'div.drop-list'
},
I however do not know how to modify the script to create a unique id for each created select.
I kow that the modification would fall in this line:
selectStructure:'<span class="left"></span><span class="center" **id="someid"**></span>
<a class="select-opener"></a>',
If i place an id in the code, then all the modified select have the same id. Is there a way to fix this?
I ran into this same issue when I received the front-end markup from an outside source. Turns out, it's a simple solution!
In the jQuery, this is currently written:
selector:'select',
It selects ALL of the 'select' elements and applies the styles to each of them. In order to fix this, add a class name or id in this line, like this:
selector:'select.classname',
OR
selector:'select#idname',
Then simply apply the class name or id to the select fields that you want the custom styles applied to.
i was trying to change the width of a particular optional value under <select> attribute, something like this. But i am getting troubled as in IE the select box along with the option value gets expanded. Is there any simple way to make the <option> only to expand and not the <select> box.. mainly in IE ....
<select width="123" style="width: 123px;">...</select>
Seems to be quite compatible solution working with all newer browsers.
This can be done using the jQuery plugin found at
http://www.jainaewen.com/files/javascript/jquery/ie-select-style/#demo
The plugin is very simple to use. Here's a breakdown of some full working code.
HTML
<select id="test" >
<option>choose on</option>
<option>aaaaaaaaaaaaaaaaaaaaaaa</option>
<option>bbbbbbbbbbbbbbbbbbbbbbb</option>
<option>ccccccccccccccccccccccc</option>
<option>ddddddddddddddddddddddd</option>
</select>
CSS
#test{
width:100px;
border:1px solid red;
}
jQuery
Don't forget to include the jQuery Js file and this plugins' Js file.
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.min.js" type="text/javascript"></script>
<script type="text/javascript" src="http://files.jainaewen.com/files/javascript/jquery/ie-select-style/jquery.ie-select-style.min.js"></script>
Then put the following right after:
<script type="text/javascript">
$('#test').ieSelectStyle();
</script>
All this should go before the closing </body> tag
Check working example at http://jsfiddle.net/7Vv8u/2/
Styling <select> items is a bit of a problem since there is no cross-browser solution without using JavaScript - since each browser handles rendering of the form controls differently.
I would suggest using an <ul> element and applying the functionality/design to act more like a <select> element - using JavaScript
this article may help you with this