jqTransform Select - Ajax Update? - javascript

I'm using the jqTransform plugin to style my form elements, which has led to a slight problem with my select boxes. It appears the select box is hidden and replaced by a custom DIV containing a list, etc.
I've managed to get the plugin firing the select's click event when something is selected from the list, but I'm having a little trouble updating the visual list - it appears the plugin doesn't support ajax update out of the box.
Does anyone have experience of performing ajax updates on selects transformed by jqTransform?
Transformed select looks something like:
<div class="jqTransformSelectWrapper" style="z-index: 8; width: 63px; ">
<div>
<span style="width: 62px; ">Petrol</span> </div>
<ul style="width: 63px; height: 24px; overflow-x: hidden; overflow-y: hidden; display: none; visibility: visible; ">
<li>Petrol</li></ul>
<select id="fuel_type_id" name="fuel_type[id]" class="jqTransformHidden" style=""><option value="1">Petrol</option></select>
</div>
The plugin won't transform an already transformed select (you can force it to by removing the jqTransformHidden class, but that just duplicates the visible select).
I wonder if there's some clever jquery I could use to return the select to it's former state and then perform the transform again?
Thanks,
Paul

following did it for me:
function fix_select(selector) {
var i=$(selector).parent().find('div,ul').remove().css('zIndex');
$(selector).unwrap().removeClass('jqTransformHidden').jqTransSelect();
$(selector).parent().css('zIndex', i);
}
fix_select('select#my_updated_select_box');

The firing of the on change event can be easily triggered by applying this fix:
http://www.polemus.net/2011/06/jqtransform-option-change-not-firing.html
For the updating I had the same problem. I fixed this with a extra function that I call after the original select gets updated.
It looks something like below:
function fix_select(selector) {
selectedVal = $(selector).children(':selected').val();
$(selector).children('option').removeAttr('selected');
$(selector).children('option[value="'+selectedVal+'"]').attr('selected','selected');
$(selector).removeClass('jqTransformHidden');
$(selector).css('display','block');
$(selector).prev('ul').remove();
$(selector).prev('div.selectWrapper').remove();
var selectElm = $(selector).closest('.jqTransformSelectWrapper').html();
$(selector).closest('.jqTransformSelectWrapper').after(selectElm);
$(selector).closest('.jqTransformSelectWrapper').remove();
$(selector).closest('form').removeClass('jqtransformdone');
$(selector).closest('form').jqTransform();
}
After you updated your select options, just trigger the following code:
fix_select('select#my_updated_select_box');
It maybe isn't the prettiest solution, but it works just wonderful for me.

Related

How do I create a calendar icon that picks dates, but doesn't show the input in pure javascript/html/css?

My goal
What is available
This is done using a simple calendar input.
<input type="date">
I have tried reducing the width of the input, but then it doesn't seem elegant as it deforms in different browsers. The previous images were on chrome. Below is how it appears in Mozilla.
I think I could specify the width for each browser. That however seems inelegant and convoluted.
In most modern browsers you can use the showPicker() method of an input[type=date] element to make the widget appear.
So, with that in mind, you could move the <input> outside of a container with overflow:hidden and trigger the widget from a click event on another element.
Something like the snippet below might work, though I wouldn't really suggest using this in a public facing web app due to the limited support :
let cal = document.querySelector('label.calendar');
let ci = document.querySelector('label.calendar input[type=date]');
cal.addEventListener('click', event => ci.showPicker());
label.calendar {
overflow: hidden;
user-select: none;
cursor: pointer;
}
label.calendar input {
position: absolute;
bottom: 100%;
left: 0;
border: 0;
padding: 0;
outline: none;
}
<label class="calendar">
<input type="date">
<span>๐Ÿ—“</span>
</label>
Instead, I would recommend you look into other (more mature) options like Smart HTML Calendar which is a Custom HTML Element.
What are you trying to achieve is not possible to do in one solution for every browser because the "date" input type is rendered by the browser and every one of them has their own specification on how to render things. You could try to use a custom component or plugin that renders a calendar using javascript/CSS/HTML that is the only way to have a consistent look and feel across different browsers.

ng-click inside ng-repeat doesn't work with :focus and display

Noob web developer here.
I want to know why this fiddle doesn't work. When you click on a link in the dropdown menu, I would expect an alert to appear, but none does. The button labeled 'yell' gives the desired behavior, but it's not a dropdown element.
Javascript
function apiCtrl($scope) {
$scope.fish = [
'blum',
'blum',
'shub'
];
$scope.yell = function() {
alert("HEY");
};
}
HTML
<div ng-controller="apiCtrl">
<button ng-click='yell()'>yell</button>
<br>
<input class='autocompleted' type='text'/>
<ul>
<li ng-repeat='f in fish' tabIndex='-1'>
<a ng-click="$parent.yell()"> {{f}}
</a>
</li>
</ul>
</div>
CSS
input.autocompleted + ul {
display: none;
}
input.autocompleted:focus + ul {
padding: 2px;
margin: 1px;
list-style-type: none;
display: block;
position: absolute;
z-index: 2;
background-color: #FFF;
border: 1px solid #000;
}
I've looked for several solutions, and while there are quite a few, none of them have the added conundrum of inexperienced css mixed in. StackOverflow won't allow me more than two links in one post, so here's one of the solutions I looked at.
As you can see, I've used $parent to dodge the ngRepeat directive's transclusion.
I tried using $rootScope to create global access to yell(), as another solution suggested. No dice.
Removing the CSS makes it work, but what is it in there that breaks Angular?
In order for click event to execute on an element, mousedown and mouseup event needs to happen on the same element. In your case as the mousedown happens, the css rule input.autocompleted + ul{display: none;} comes into picture as you lose focus from the input, eventually mouseup never happens on that element and no click event executes. You can test this by changing <a ng-click="yell()"> to <a ng-mousedown="yell()"> and you will see the alert happening. Also a typical autocomplete does not show the items on click of the textbox instead generally when you type the characters in the suggestions show up. Possibly when you implement that you should not get into these issues.
Fiddle
On a side note, it would be better to use module.controller('controllerName', constructorWithDep) syntax since global scope controller discovery will be broken (Can opt in though) with version 1.3.
Another thing to mention that usage of $parent is not a good practice, instead you could use . syntax on the items being bound on the child scope. In your case you don't need that at all since yell is a function defined on its parent scope and is a reference type it will be automatically carried down via prototypical inheritance to its child scope(s).

Javascript to get data but IE cannot show data apporiately

I not sure the reason or how to explain it clearly, but my web UI is all great in firefox and crome.
I use httprequest to get data and show information in UI dynamically, but only IE cannot shows data correctly.
I use a block to change the innerHTML depends on the data returned, and the UI are <select> and <ul><li>.
My block is like that:
<ul id="roomlist" class="room_menu">
<li id="allroom" class="txtunderline" style="text-align: right;">All Room</li>
</ul>
There is an original li called 'allroom', after get data from server, the block 'roomlist' will change the innerHTML.
In function onreadystatechange, I get some data and put into array, then change roomlist like:
first, add the last li called 'createroom'
var createRoom="<li id=\"createroom\" class=\"txtunderline\"><div style=\"text-align: right;\">"+"CreateRooms"+"</div></li>";
$("#allroom").after(createRoom);
then add each li of rooms, but IE(I tried IE8, IE10) just show the allroom and createroom, others not showned. I guess maybe that is because other <li> is customized with image like:
var oldRoom="<li id=\"room"+index+"\">";
oldRoom+="<table style=\"width: 100%; position: relative; top: -2px; left: -2px;\"><tr><td><img width=\"28px\" height=\"28px\" src=\"images/location/" + locatImg[index] + "\" /></td><td align=\"right\">" + locatInfo[index]+"</td></tr></table></li>";
$("#createroom").before(oldRoom);
The result may like that in crome or firefox:
but in IE:
If I look the DOM in google will be:
And I use <select> to show the data is empty, too.
I have debugged by alert data, and alert function is ok( can use javascript), but when I alert the data I get, the alert not triggered. It let me guess there may something wrong so the alert cannot pop up until the bug be solved.( but the status bar of IE not show any wrong messages)
I use jQuery, the version is:
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
I heard that jQuery not compatible since version 2.0 released, but my version seem not 2.0 version?
And the same kind list(<ul><li> pairs) in other pages are shown well, and there is no image added to the list.
I beat my brains out and hope someone can help me to find out the real problems, any help appreciate!
Edit: Sorry, I try to simplify the list just display text like:
var oldRoom="<li id=\"room"+index+"\">" + locatInfo[index] + "</li>";
$("#createroom").before(oldRoom);
And in IE it still the same:
while in crome the structure is:
Try to reengineer your code to use less inline CSS, and take the tables out. Your approach is very scattered, and you could be running into style conflicts or other issues. For example that position style could be the source of your problem, but it's difficult to know because your markup isn't very semantic.
And it should be noted you're appearing to use tables incorrectly, however it could be that you've just left out a lot of the extra room information that would make this a tabular list of information.
In the case that you are ONLY displaying your room with an icon, you can simply make a series of CSS classes with the background images you want, and then assign the correct class to the <li>.
For example your CSS could include:
ul#roomList, ul#roomList li {
padding: 0;
margin: 0;
list-style: none;
}
ul#roomList li {
width: 10em;
height: 28px;
text-align: right;
text-decoration: underline;
background-color: #A0A0A0;
}
ul#roomList li.roomType1 {
background-image: url('/images/room1.png');
}
ul#roomList li.roomType2 {
background-image: url('/images/room3.png');
}
ul#roomList li.roomType3 {
background-image: url('/images/room3.png');
}
And in your HTML you would simply use:
<ul id="roomList">
<li class="roomType3">Some text for room 3</li>
<li class="roomType1">Some text for room 1</li>
</ul>
However if you really do want to display tabular data, you should not use an unordered list. Instead you should use nothing but a table, and then append rows (<tr>) as necessary. Just make sure you don't put the "All rooms" and "Create room" functional buttons into your table, as those are not tabular data.
A lot of this becomes important later when you are trying to advertise your hotel on search engines. Proper semantic layout is much easier for a search engine to dissect and advertise.
Ok, I find that the httprequest in IE too slowly to get data when I want to change innerHTML of the list. It's my fault, I think I should ensure that the data is received before change UI.

select with multiple selection option but in a proper dropdown way

I have a simple city drop down in which I want to use multiple selection option.
For it I used multiple attribute of select tag but by using it the drop down got converted to a box shaped area with multiple select option.
What I want is that drop down look should stay as it is i.e. on clicking the select drop down should appear and in it I can use multiple cities with CTRL and whose values then will be used in a php script.
I have seen multiple jquery scripts for it but I wanted to know if is there some simple way to do this instead of using any jquery or something.
Is there any simpler method to do so???
please try below code:
<select id="city" multiple="multiple" name="city[]">
<option>hawaii</option>
<option>michigan</option>
<option>southfield</option>
</select>
and you get multiple city value in php
echo $_POST['city'];
HTML dropdown is made that way, does not allow multiple selections but you can use some jquery plugin like this for doing that and it is much simpler than creating such plugin yourself.
In principle, the size=1 attribute in select would tell the browser to show just one option, and you could use scripting to change the value of the size property to create a dropdown effect. In practice, it mostly does not work.
A more practical approach is to set the height of the select element initially and then change the height on mouseover and when focused. Unfortunately browser behavior is not consistent in sizing the element, but the results might be tolerable. Note that the font size in options is reduced by default, so sizing is a bit tricky. In this example I simply set the font size to 100% so that the em unit can be used in a simple manner:
option { height: 1.3em; font-size: 100%; }
select { height: 1.3em; font-size: 100%; }
select:hover, select:focus { height: 13em; }
The result is a little too small on some browsers and a little too large on some, and IE does not show any arrow to indicate that itโ€™s really a dropdown.

Custom Checkbox

Hello i am trying to create a custom checkbox for my website like the image link provided. What would be the best way to go around doing this?
Many thanks.
There is a CSS trick that actually works by hiding the checkbox (or radio), defining a label (which in all relevant browsers will turn the checkbox on/off) that will be the visual representation, and using the :checked and + selectors.
This is just a simple example:
.foscheck input { display: none; }
.foscheck label { display: block; width: 20px; height: 20px; background: red; }
.foscheck input:checked + label { background: blue; }
<div class="foscheck">
<input type="checkbox" id="fos1" />
<label for="fos1"></label>
</div>
jsFiddle Demo
Downsides: the :checked selector unfortunately does not work on IE, only from IE9. You can apply a Javascript fallback only for IE through conditional comments though.
Note: For accessibility, you should have some text describing the checkbox in the label, I just wanted to illustrate the effect.
jQuery is your best bet, this is a checkbox plugin for example, but there are hundreds of them so something else may suit you better. Just google 'jquery custom checkbox'.

Categories