Delegate JS events to different objects - javascript

I'm trying to re-skin the input type file element.
I do this by placing two elements on top of each other. One of them is the input tag and the other is a nice button. Something like this:
<input type="file" id="filesButton" multiple>
<input type="button" id="filesButtonOverlay" value="Add Files">
The button has some nice effects when a user hovers, clicks, etc (all done is CSS). However since the input-type-file has a higher z-index (needs to be the case since you can't emulate a click on it) all these effects don't show.
Is there a nice way to delegate all events that input-type-file gets and trigger them on the button?

What if you wrapped the inputs in a div and attached the events to the div? Then target your button with your changes?

I would think you should be able to do this with a shared parent. Then you place the hover on the parent rather than the button itself.
<span id="wrapper">
<input type="file" id="filesButton" multiple>
<input type="button" id="filesButtonOverlay" value="Add Files">
</span>
$("#wrapper").hover(function(){
$("#filesButtonOverlay").dosomething();
});
or in CSS:
#wrapper:hover #filesButtonOverlay{
stuff:
}
If you could potentially have multiple on the same page, you'd want to change to using classes instead of ids

Related

GTM Event on Content

I can't see to find an answer to this one anywhere. I'm trying to setup a trigger and event tag in Google Tag Manager to fire whenever content is present. Essentially, I am creating a simple event in Google Analytics for Product Views. The developer for this site is expensive, so I'd like to handle it purely in GTM.
One piece of content that only exists on product pages is the submit on the cart button.
Can anyone recommend a method to inject some code with GTM to fire when content exists so I can trigger a tag off it?
Here is the html in and around the cart button. I'm thinking that I can fire something when class="clsAddCartRight" exists or the submit - either one:
<div id="variationGroup" class="clsViewItemVariationGroup clsOverflow" style="clear:both;">
<div class="clsViewItemVariationList clsOverflow" style="width:200px;margin:0 auto;">
<select name="item_variations" id="item_variations_496" onchange="getDetails()">
<option value="1606" selected="selected">Medium</option>
<option value="1607">Large</option>
</select>
</div>
<div class="clsItemSaleDetailBlockBottom">
<form name="purchaseItemFrm" id="purchaseItemFrm" action="http://www.runwaycrush.com/marketplace/cart.html" method="post">
<input type="hidden" name="item_id" id="item_id" value="1602">
<input type="hidden" name="c_action" id="c_action" value="add">
<input type="hidden" name="item_ref" id="item_ref" value="kanduclothing">
<input type="hidden" name="item_matrix_id" id="item_matrix_id" value="4721">
<div class="clsItemCartBlock clsFloatRight" id="addCartButton" style="margin:20px auto 0px; width:318px;">
<div class="clsAddCartLeft">
<div class="clsAddCartRight">
<input type="submit" name="add_to_cart" id="add_to_cart" value="ADD TO CART">
</div>
</div>
</div>
</form>
</div>
</div>
You can use a DOM type variable in GTM and use the "CSS Selector" option to select the element by classname (if the same class is there multiple times it will pick the first occurence). If you set the attribute name field to "class" the value for that variable will be the value of the class attribute.
Actually I think it would be better if you use the button itself and look for the "id" attribute with the value of "add_to_cart", because ids are unique per page (or should be).
However you also need an event to trigger a tag.
The value will be available only after the DOM has rendered. So the easiest way would be to set up a pageview and set the trigger type to "DOM Ready" and have if only fire when the value of your DOM variable matches the classname (or id respectively) of the button.
However if your product page urls follow any recognizable pattern it would be a lot better to use a url filter in a pageview trigger. That way you could have your tags trigger on pageload, which for many tags is much preferable.

Why customized radio buttons are not getting disabled?

I am using this plugin to customize check boxes and radio buttons on a page.
These radio buttons are in a div#Main element which comprise of some other HTML elements also. I need to disable everything in this div on a button click (I am using jQuery). For this I have the following code,
HTML
<input type="button" id="DisableElements" value="Disable elements" />
<div id="Main">
<input type="radio" class="styled" name="reg-all"/>
<input type="radio" class="styled" name="reg-all"/>
<select id="MyList">
<option value="1">Choice-1</option>
<option value="2">Choice-2</option>
</select>
<textarea id="Comments" rows="4" cols="5"></textarea>
</div>
Script
$(function(){
$('#DisableElements').click(function(){
$('#Main').find('*').attr('disabled', 'disabled');
});
});
Issue: Everything got disabled correctly except the radio buttons.
Behind the scenes, the plugin script hides the actual radio button and
put a span over the radio buttons like a blanket. This span has
got a background image sprite with different states (on and off) which
gets updated accordingly on radio button selection. This was the
working of this plugin.
I could have used the inbuilt method of the plugin to disable/destroy the functionality but I did not find any method for this.
images loads with little delay after the DOM has finished loading,
so you can try calling your function in $(window).load().
hope it will help.
The solution i made can be thought of as a patch but works nice (for my scenario at least). What should have been the right approach for this would be using some existing API method to reflect the change, something like disable() or similar but i did not find such method or something like this.
Solution: Making the radio buttons appear like disable (non clickable).
Because i do not want to dig into the plugin js file. For this i made a transparent div with some width and height enough to cover the radio buttons and place it over them like a layer between radio buttons and cursor. This div is hidden by default and show this while making controls disable. keeping it short and sweet, here are the code changes.
HTML
<input type="button" id="DisableElements" value="Disable elements" />
<div id="Main">
<div id="Blanket"></div>
<input type="radio" class="styled" name="reg-all"/>
<input type="radio" class="styled" name="reg-all"/>
<select id="MyList">
<option value="1">Choice-1</option>
<option value="2">Choice-2</option>
</select>
<textarea id="Comments" rows="4" cols="5"></textarea>
</div>
CSS - for blanket div
#Blanket
{
position:absolute; /*Imp: otherwise it will disturb the UI*/
width:100px;
height:100px;
display:none;
/* top/left adjustments, if required! */
}
Script
$(function(){
$('#DisableElements').click(function(){
$('#Blanket').show();
$('#Main').find('*').attr('disabled', 'disabled');
});
});
This solution however needed to drop the fear of what if someone using developer tools to out smart the application but that does not matter any way. Besides, you can-not 100% block the user from using such tools.
Another solution which worked and looks more appropriate: Placing invisible blanket over input controls sounds like a patch and can be easily snapped. The plugin script adds a CSS class named styled and requires to add following styles to achieve customized look and feel.
input.styled
{
display: none; // hides the parent input element
}
Because of this, even if we switch button states to disable, the changes did not reflect because the parent element was hidden making the other listeners difficult to attach. By changing the styles to following, everything worked.
input.styled
{
position: absolute;
opacity: 0;
}
It makes the parent input element invisible but completely active on DOM behind the scenes.

How to link an input button to a file select window? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Jquery trigger file input
I'm working on a form which allows users to upload images to a website. So far I have got a drag and drop solution working in Chrome and Safari. However I also need to support the action of users clicking a button and browsing for files in the traditional manner.
Similar to what this would do:
<input type="file" name="my_file">
However rather than having the clunky file description area and un-editable Browse button I would rather use something like this:
<input type="button" id="get_file">
My question therefore is how to I make this button open a file selection window and process the selection the same way that type="file" would work?
Cheers.
My Solution
HTML:
<input type="button" id="my-button" value="Select Files">
<input type="file" name="my_file" id="my-file">
CSS:
#my-file { visibility: hidden; }
jQuery:
$('#my-button').click(function(){
$('#my-file').click();
});
Working in Chrome, Firefox, and IE7+ so far (haven't tried IE6).
You could use JavaScript and trigger the hidden file input when the button input has been clicked.
http://jsfiddle.net/gregorypratt/dhyzV/ - simple
http://jsfiddle.net/gregorypratt/dhyzV/1/ - fancier with a little JQuery
Or, you could style a div directly over the file input and set pointer-events in CSS to none to allow the click events to pass through to the file input that is "behind" the fancy div. This only works in certain browsers though; http://caniuse.com/pointer-events
If you want to allow the user to browse for a file, you need to have an input type="file" The closest you could get to your requirement would be to place the input type="file" on the page and hide it. Then, trigger the click event of the input when the button is clicked:
#myFileInput {
display:none;
}
<input type="file" id="myFileInput" />
<input type="button"
onclick="document.getElementById('myFileInput').click()"
value="Select a File" />
Here's a working fiddle.
Note: I would not recommend this approach. The input type="file" is the mechanism that users are accustomed to using for uploading a file.

input type=file attached to an onclick event

I have a menu like this:
<ul class="sub">
<li>New</li>
<li>Open</li>
<li>Save</li>
<li>Help</li>
</ul>
and I'd like to attach an onclick even to the Open li that would kick off a file open dialog, like input type="file" does. I can handle attaching code to the li's onclick event, but I don't know what code to attach.
TIA
You can add a normal input type="file" to the page and style it to be hidden. Something like this:
<input type="file" id="theFileInput" style="display:none;" />
(Only using in-line styling for this example, I recommend separating the style from the markup of course.)
Then you can initiate a click on it in response to a click event on the target element. With jQuery (assuming you can set an id on the li, or otherwise uniquely identify it in the selector in some way) it would be something like:
$('#clickableLiElement').click(function() {
$('#theFileInput').click();
});
The input type="file" is still there and can be interacted with just like any other form element. It's just invisible to the user. But this would launch the Open File dialog and set its value to the element normally, which can be included in the POST to the server normally.
With JavaScript
<input type="file" accept="images/*" name="images" id="images" onClick="showModal()" style="display:none"/>
<script>
function showModal(){
document.getElementById('images').click();
}
</script>
<li onClick="showModal()"></li>
The answer above (David) works, but in your css file you need to do:
opacity: 0;
-moz-opacity: 0;
filter:alpha(opacity=0);
The display:none solution is not working with Chrome or Safari.

Cannot enable XHTML submit input/button which is disabled by default

I have this simple button in XHTML:
<input type="submit" name="submit" value="Test" disabled="disabled" onmouseover="this.disabled=''" />
The problem is, no matter what I try, when I hover over the button, it won't re-enable from the disabled attribute it has. In XHTML, you are required to use disabled="disabled" which seems to completely break the option to enable/disable it with JavaScript. I've tried running this.disabled='', this.disabled=false, and even this.removeAttribute('disabled') but nothing seems to be capable of re-enabling the button. Weird thing is, if I remove the ='disabled' part of the attribute (making it invalid XHTML), the script enables the button just fine. Is this not possible without using invalid XHTML?
Note: I'd really prefer to only use JavaScript for this specific example, not jQuery.
I thought this would be something simple that would take like 5 seconds but apparently not.
Disabled elements for some reason do not seem to fire mouseover/out events along with click.
The following is not the best solution in the world, but you can wrap it in another element and use the wrapping element's mouseover event to enable it.
<div style="display:inline-block;padding:1px;" onmouseover="document.getElementById('submit').disabled=false">
<input type="submit" id="submit" name="submit" value="Test" disabled="disabled" />
</div>
disabled=false is correct.
The problem is that a disabled element doesn't receive events. See the question Javascript OnMouseOver and Out disable/re-enable item problem.

Categories