I have div which it is hidden by default , when the use clicks show link the following javascript method is called:
function ChangeControlVisibility(elementID) {
var element = $("#" + elementID);
if (element.css('display') != 'block' && element.css('display') != 'table') {
element.show();
var tempElement = $('div.expanded');
if (tempElement.length > 0) {
tempElement.css('background-image', 'url(../images/arrow1.gif)');
}
}
else {
element.hide();
var tempElement = $('div.expanded');
if (tempElement.length > 0) {
tempElement.css('background-image', 'url(../images/arrow2.gif)');
}
}
}
this step works but when i call the previous method at page_load event the method doesn't work:
element.css('display') undefined.
Is there any problem at the previous code????
Do you execute that code within the .ready() handler?
And by the way, unless you really need to explicitly check for display-state table, you could just ask for
$(document.ready(function(){
if (!element.is(':visible')){
}
else{
}
});
Ref.: .is(), .ready(), :visible
You can simplify it overall by using .toggle() and the :visible selector, like this:
function ChangeControlVisibility(elementID) {
var vis = $("#" + elementID).toggle().is(':visible');
$('div.expanded').css('background-image', 'url(../images/arrow' + (vis ? '1' : '2') + '.gif)');
}
This toggles the visibility (via .hide()/.show() under the covers) and checks the resulting visibility to see if it's shown in the page or not, and sets the arrow image according to this.
Have a look at the :hidden and :visible jQuery selector. and try something like this:
function ChangeControlVisibility(elementID) {
var hiddenElement = $("#" + elementID + ":hidden");
var element = $("#" + elementID);
if (hiddenElement.length > 0) { //to check if this element exists
hiddenElement.show();
var tempElement = $('div.expanded');
if (tempElement.length > 0) {
tempElement.css('background-image', 'url(../images/arrow1.gif)');
}
}
else {
element.hide();
var tempElement = $('div.expanded');
if (tempElement.length > 0) {
tempElement.css('background-image', 'url(../images/arrow2.gif)');
}
}
}
Related
How do I track via GTM if certain element have impressions? Let say I would like to know how many times this element have been seen?
<div class="box"><div> class"text"><span>Text</span</div</div>
You could create a custom JavaScript variable to check if an element with the .box class exists.
Something like:
if(document.getElementsByClassName("box")){
return true;
} else {
return false;
}
You can then use this in your trigger (eg. your custom variable > equals > true).
You can track impressions with one custom HTML tag and a custom event trigger. You need to attach an event listener to a function that checks if the element is visible on the page:
<script>
var hasDeals = document.getElementsByClassName('box').length;
var element = document.getElementsByClassName('box')[0];
var elVisible = false;
var eventPushed = false;
if(hasDeals>0) {
document.addEventListener("scroll", function() {{isScrolledIntoView(element);}} );
}
function isScrolledIntoView(el) {
if(!elVisible) {
var elemTop = el.getBoundingClientRect().top;
var elemBottom = el.getBoundingClientRect().bottom;
var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
elVisible = isVisible;
return isVisible;
} else if(!eventPushed) {
dataLayer.push({'event': 'dealVisible'});
eventPushed = true;
}
}
</script>
From there on you just need to create the trigger and use it as you wish.
You can find more explanations about how this script works and how to edit it for other scenarios here: Tracking Elements Impression with Google Tag Manager
I have an AutoCompleteExtender from the Ajax Control Toolkit. I need to have a heading in the dropdown list that shows how many items found, but it should not be selectable as an item.
I have tried this using jQuery, but even when I just add as a div, it is still selected as an item into the text box when I click on it:
function clientPopulated(sender, e) {
var completionList = $find("AutoCompleteEx").get_completionList();
var completionListNodes = completionList.childNodes;
for (i = 0; i < completionListNodes.length; i++) {
completionListNodes[i].title = completionListNodes[i]._value.split(':')[2];
}
var resultsHeader;
if(completionListNodes.length==1000)
resultsHeader = 'Max count of 1000 reached.<br/>Please refine your search.';
else if(completionListNodes.length>0)
resultsHeader = completionListNodes.length + ' hits.';
else
resultsHeader = msg_NoObjectsFound ;
jQuery(completionListNodes[0]).before('<div>' + resultsHeader + '</div>');
}
Add OnClientItemSelected and OnClientShowing events handlers and try script below:
function itemSelected(sender, args) {
if (args.get_value() == null) {
sender._element.value = "";
}
}
function clientShowing() {
var extender = $find("AutoCompleteEx");
var optionsCount = extender.get_completionSetCount();
var message = "";
if (optionsCount == 1000) {
message = 'Max count of 1000 reached.<br/>Please refine your search.';
}
else if (optionsCount > 0) {
message = optionsCount + " hits."
}
else {
message = "oops."
}
jQuery(extender.get_completionList()).prepend("<li style='background-color:#ccc !important;'>" + message + "</li>");
}
Added:
you even can do this without OnClientItemSelected handler:
function clientShowing() {
var extender = $find("AutoCompleteEx");
var oldSetText = extender._setText;
extender._setText = function (item) {
if (item.rel == "header") {
extender._element.value = "";
return;
}
oldSetText.call(extender, item);
};
var optionsCount = extender.get_completionSetCount();
var message = "";
if (optionsCount == 1000) {
message = 'Max count of 1000 reached.<br/>Please refine your search.';
}
else if (optionsCount > 0) {
message = optionsCount + " hits."
}
else {
message = "oops."
}
jQuery(extender.get_completionList()).prepend("<li rel='header' style='background-color:#ccc !important;'>" + message + "</li>");
}
We can give a better answer if you post the output html of your autocomplete control. Anyway if its a dropdown control;
jQuery(completionListNodes[0]).before('
<option value="-99" disabled="disabled">your message here</option>'
);
The answer by Yuriy helped me in solving it so I give him credit although his sollution needed some changes to work.
First of all, the clientShowing event (mapped by setting OnClientShowing = "clientShowing" in the AutoExtender control) is executed on initialization. Here we override the _setText method to make sure nothing happens when clicking on the header element. I have used the overriding idea from Yuriy's answer that really did the trick for me. I only changed to check on css class instead of a ref attribute value.
function clientShowing(sender, e) {
var extender = sender;
var oldSetText = extender._setText;
extender._setText = function (item) {
if (jQuery(item).hasClass('listHeader')) {
// Do nothing. The original version sets the item text to the search
// textbox here, but I just want to keep the current search text.
return;
}
// Call the original version of the _setText method
oldSetText.call(extender, item);
};
}
So then we need to add the header element to the top of the list. This has to be done in the clientPopulated event (mapped by setting OnClientPopulated = "clientPopulated" in the AutoExtender control). This event is executed each time the search results have been finished populated, so here we have the correct search count available.
function clientPopulated(sender, e) {
var extender = sender;
var completionList = extender.get_completionList();
var completionListCount = completionList.childNodes.length;
var maxCount = extender.get_completionSetCount();
var resultsHeader;
if(completionListCount == maxCount)
resultsHeader = 'Max count of ' + maxCount + ' reached.<br/>'
+ 'Please refine your search.';
else if(completionListCount > 0)
resultsHeader = completionListCount + ' hits.';
else
resultsHeader = 'No objects found';
jQuery(completionList).prepend(
'<li class="listHeader">' + resultsHeader + '</li>');
}
I have also created a new css class to display this properly. I have used !important to make sure this overrides the mousover style added from the AutoExtender control.
.listHeader
{
background-color : #fafffa !important;
color : #061069 !important;
cursor : default !important;
}
I have four controls in a page with update panel. Initially mouse focus is set to first control. When I partially post back the page to server the focus automatically moves to first control from the last focused control from the control I have tabbed down to. Is there any way to maintain the last focus?
Take a look at Restoring Lost Focus in the Update Panel with Auto Post-Back Controls:
The basic idea behind the solution is to save the ID of the control
with input focus before the update panel is updated and set input
focus back to that control after the update panel is updated.
I come with the following JavaScript which restores the lost focus in
the update panel.
var lastFocusedControlId = "";
function focusHandler(e) {
document.activeElement = e.originalTarget;
}
function appInit() {
if (typeof(window.addEventListener) !== "undefined") {
window.addEventListener("focus", focusHandler, true);
}
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(pageLoadingHandler);
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler);
}
function pageLoadingHandler(sender, args) {
lastFocusedControlId = typeof(document.activeElement) === "undefined"
? "" : document.activeElement.id;
}
function focusControl(targetControl) {
if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
var focusTarget = targetControl;
if (focusTarget && (typeof(focusTarget.contentEditable) !== "undefined")) {
oldContentEditableSetting = focusTarget.contentEditable;
focusTarget.contentEditable = false;
}
else {
focusTarget = null;
}
targetControl.focus();
if (focusTarget) {
focusTarget.contentEditable = oldContentEditableSetting;
}
}
else {
targetControl.focus();
}
}
function pageLoadedHandler(sender, args) {
if (typeof(lastFocusedControlId) !== "undefined" && lastFocusedControlId != "") {
var newFocused = $get(lastFocusedControlId);
if (newFocused) {
focusControl(newFocused);
}
}
}
Sys.Application.add_init(appInit);
I find this more elegant:
(function(){
var focusElement;
function restoreFocus(){
if(focusElement){
if(focusElement.id){
$('#'+focusElement.id).focus();
} else {
$(focusElement).focus();
}
}
}
$(document).ready(function () {
$(document).on('focusin', function(objectData){
focusElement = objectData.currentTarget.activeElement;
});
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(restoreFocus);
});
})();
I have an ASP.NET code-behind page linking several checkboxes to JavaScript methods. I want to make only one JavaScript method to handle them all since they are the same logic, how would I do this?
Code behind page load:
checkBoxShowPrices.Attributes.Add("onclick", "return checkBoxShowPrices_click(event);");
checkBoxShowInventory.Attributes.Add("onclick", "return checkBoxShowInventory_click(event);");
ASPX page JavaScript; obviously they all do the same thing for their assigned checkbox, but I'm thinking this can be reduced to one method:
function checkBoxShowPrices_click(e) {
if (_hasChanged) {
confirm(
'All changes will be lost. Do you wish to continue?',
function(arg) {
if (arg.toUpperCase() == 'YES') {
var checkBox = document.getElementById('<%=checkBoxShowPrices.UniqueID%
>');
checkBox.checked = !checkBox.checked;
eval("<%=base.GetPostBackEventReference(checkBoxShowPrices)%>");
_hasChanged = false;
}
});
return false;
} else {
eval("<%=base.GetPostBackEventReference(checkBoxShowPrices)%>");
}
}
function checkBoxShowInventory_click(e) {
if (_hasChanged) {
confirm(
'All changes will be lost. Do you wish to continue?',
function(arg) {
if (arg.toUpperCase() == 'YES') {
var checkBox = document.getElementById('<%
=checkBoxShowInventory.UniqueID%>');
checkBox.checked = !checkBox.checked;
eval("<%=base.GetPostBackEventReference(checkBoxShowInventory)%>");
_hasChanged = false;
}
});
return false;
} else {
eval("<%=base.GetPostBackEventReference(checkBoxShowInventory)%>");
}
}
Add to the event the checkbox that is raising it:
checkBoxShoPrices.Attributes.Add("onclick", "return checkBox_click(this, event);");
Afterwards in the function you declare it like this:
function checkBoxShowPrices_click(checkbox, e){ ...}
and you have in checkbox the instance you need
You can always write a function that returns a function:
function genF(x, y) {
return function(z) { return x+y*z; };
};
var f1 = genF(1,2);
var f2 = genF(2,3);
f1(5);
f2(5);
That might help in your case, I think. (Your code-paste is hard to read..)
How to get ClientID of a TreeNode in a TreeView based on one of its rendered attributes,
for example, its title attribute (In my case it's unique)
,using either Server-Side or Client-Side code?
I go with this code, but it doesn't work, any suggestion?
// Retrieves TreeNode ClientID.
function GetTreeNodeID(nodeTitle)
{
var treeNodes = document.getElementById('tvMenu').childNodes;
var treeLinks;
for(var i=0 ; i<treeNodes.length ; i++)
{
treeLinks = treeNodes[i].getElementsByTagName('a');
for(var j=0 ; j<treeLinks.length ; j++)
{
if(nodeTitle == treeLinks[j].title && treeLinks[j].title != "");
{
alert("Par: " + nodeTitle);
alert("Title: " + treeLinks[j].title);
return treeLinks[j].id;
}
}
}
}
The above code that is mentioned with the question always returns the id of root node, any suggestion?
innerText or innerHtml or textContent ? Wich browser do you use ?
function GetTreeNodeID(nodeInnerText)
{
var tree = document.getElementById('tvMenu');
var treeLinks = tree.getElementsByTagName('A');
for(var element in treeLinks )
{
if((nodeInnerText == treeLinks[element].innerText) && (treeLinks[element].innerText != ""))
{
alert("Par: " + nodeInnerText);
alert("innerText: " + treeLinks[element].title);
return treeLinks[element].id;
}
}
}
Look here for a sample code.