scrollIntoView not defined - javascript

I have the following problem.
I have a tree view control in .NET and I have created a autocomplete search box to search the tree for a name - which then I can select and it highlights the item with a selected class.
The tree view is pretty long so I have given it a height and overflow scroll.
The problem is that I want view or scroll down to the selected item when I've searched for it.
So i have created the following script to scrollIntoView it but this doesn't seem to work:
function search_itemSelected(sender, e) {
var hdSearchID = $get('<%= hdSearchID.ClientID %>');
hdSearchID.value = e.get_value();
var selectedElement = $("div.node.cen.selected"); // This works
if (selectedElement != null) {
selectedElement[0].scrollIntoView = 10; // This keeps coming back as undefined
}
}

First: change
if (selectedElement != null)
to
if (selectedElement.length)
because $("div.node.cen.selected"); will never return null. jQuery always returns a jQuery object (empty or not, but a jQuery object)
So in the case where it is empty, the selectedElement[0] will return undefined and thus the scrollIntoView does not exist..
Second: scrollIntoView is a function and so you do not assign a value to it. You need to call it with
selectedElement[0].scrollIntoView();

scrollIntoView is used with element you want to show, like that :
el.scrollIntoView(true);
Note:
Scrolls the window until the element is visible.
Syntax:
document.all.elementID.scrollIntoView(param1)
Parameters:
param1 Optional; true or false, indicating whether the top of the element
is scrolled to the top of the window or the bottom of the
element is scrolled to the bottom of the window.
Moreover, scrollIntoView() can only be used with some tags
http://www.java2s.com/Code/JavaScriptReference/Javascript-Methods/scrollIntoViewisappliedto.htm

Related

Does Dragula accepts buffer the answer?

I'm using dragula and wanted to have a heading within each container. I've managed to make the heading non-draggable via the moves attribute, but, then I also wanted to prohibit that elements can be dropped above the heading so I added:
accepts: function (el, target) {
var itemPos = Array.from(el.parentNode.children).indexOf(el);
var acceptDrop = itemPos > 0;
console.log("Accept Drop = " + acceptDrop);
return acceptDrop;
},
In the console log, I can see that the acceptDrop is false when I move an element to the first position but the drop is possible anyway! But then I can't move it from that position. I.e. If the accepts returns false when the drag is initiated I can't drop the item anywhere, but if it starts with true I can drop it everywhere. Am I missing something or how can I make this dynamic and prevent drops at position zero?
(I know that I can put the heading outside the container with draggable items but that needs extra HTML nesting that shouldn't be needed)

Error if targeting multiple element Id's with Javascript and one of then is not found

I am trying to target multiple IDs with JavaScript so that I can disable the input field for them. It seems to be pretty straight forward using the following script, but I noticed that on pages where the middle Element does not exist, the script does not disable the 3rd one (as though it just stops working when not finding the second element).
<script>
document.getElementById("id_1").disabled = true;
document.getElementById("id_2").disabled = true;
document.getElementById("id_3").disabled = true;
</script>
So on pages when all 3 IDs exist, the script works perfectly. But on pages where either "id_1" or "id_2" does not exist, the remaining elements are not disabled even if they do exist.
Is there any way around that? Note that I can not create separate scripts for each page because this will go in the footer which is the same for all pages.
Thanks!
You should test for the existence first, then disable it if it exists. I also put the id's in an array to simplify the code.
var ids = ['id_1','id_2','id_3'];
for (var i = 0; i < ids.length; i++) {
var el = document.getElementById(ids[i]);
el && (el.disabled = true);
}
<input id="id_1" value="id_1">
<input id="id_3" value="id_3">
This is because document.getElementById returns null when the element has not been found, so effectively you're causing an exception while trying to set disabled on null. This would be the case when one of the elements are not set in the DOM. What you will have to do is check whether the element has been found correctly then set the element or loop through them all.
TL;DR:
The reason that the script stops working is that it is throwing an error when you try to disable an element that doesn't exist.
In Detail:
document.getElementById() will return null if the element that you tried to find does not exist (Here's the MDN page).
When you try to set the .disabled property to true on null JavaScript will throw a TypeError. Unless you handle that error with a try/catch block it will cause your script to stop executing and the later input elements will not become disabled.
Solution
To fix this you'll want to check that your element actually is an element before trying to set it to disabled. Something like this:
var el = document.getElementById('id_1');
if ('null' !== typeof el) {
el.disabled = true;
}

Retrieve html code of selected text

In mozilla, I can select a text and print the selected text using contentWindow.getSelection(). But I am trying to get the underlying html code block for this selected text. Is there any way I can retrieve it?
I need to extract urls and other informations like src, etc. underneath any clickable text that a user selects. I need the code block of its parent node.
Thanks.
Retrieving the HTML should be relatively easy, but it depends on what you are wanting. window.getSelection() returns a selection object. You can use:
window.getSelection().anchorNode to obtain the Node in which the selection begins and
window.getSelection().focusNode to get the Node in which the selection ends.
For instance:
let selection = contentWindow.getSelection();
let firstElement = selection.anchorNode;
let lastElement = selection.focusNode;
What you do once you have the nodes/elements will depend on what it is that you are actually wanting to find. You have not specified that, so manipulating it past finding those nodes would just be a guess as to what you are wanting. For instance, you just might want to find the parent of the anchorNode, verify that it contains the focusNode (firstElement.parentNode.contains(lastElement)) (if not then continue finding the next parent until it does) and use the parent's innerHTML. Alternately, maybe you want to find the first parent element of the anchorNode which contains the focusNode and then use a TreeWalker to walk the DOM tree until you find the anchorNode and start accumulating the HTML until you encounter the focusNode.
Do you have a mouse event listener or something before you do contentWindow.getSelection?
If you do you can get the selected node by doing:
function onMouseUp(event) {
var aWindow = event.target.ownerDocument.defaultView;
// should test if aWindow is chrome area or actually content area
var contentWindow = aWindow.document instanceof Ci.nsIHTMLDocument ? aWindow : null; // i guessed here but testing if its content window is done in some similar way
if (!contentWindow) { return }
// do contentWindow.getSelection im not familiar with the code, if selection exists // check if more then one range selected then get node for each, however im going to assume only one range is selected
var nodeOfFirstRange = event.explicitOriginalTarget
var elementOfNode = nodeOfFirstRange.parentNode;
var htmlOfElement = elementOfNode.innerHTML;
}
Services.wm.getMostRecentWindow('navigator:browser').gBrowser.addEventListener('mouseup');
issue with this code is if user mouses down in content window and then highlights and mouseup while mouse its outside of content window, like on chrome window or even outside the browser (like if the browser window was not in maximum or if user mousedup in taskbar of os etc) so just use this code as a guide

How to hide a *single* MVC/Kendo tabstrip tab?

How do I hide a single tab on a MVC/Kendo UI tabstrip?
I want to hide a tab based on a condition. My jQuery code goes like this:
//authUser is a hidden input whose value is set in the controller and passed into the view
if ($('#authUser').val() == 'False') //hide the last tab
{
$($("#tabstrip").data("kendoTabStrip").items()[6]).attr("style", "display:none");
}
When I run the code I get the following error on the line of code that's executed if authUser is False:
JavaScript runtime error: Unable to get property 'items' of undefined or null reference
Ideas?
The fact that 'items' is undefined implies that you never appropriately selected the tabstrip in the first place. Either your CSS selector is wrong (are you sure you named it tabstrip?) or you did not follow the Kendo method names appropriately.
Here are two ways I found to hide the last tab:
Hiding the last tabstrip element
var tabStrip = $("#tabstrip").kendoTabStrip().data("kendoTabStrip");
//Find the last tab item's index from the items list
var lastIndex = tabStrip.items().length - 1;
//Use jQuery's hide method on the element
$(tabStrip.items()[lastIndex]).hide();
Using Kendo's tabstrip remove method
I believe the following is more appropriate. Why not use the tabstrip's remove method and completely remove it from the DOM since the user should not have access anyway?
var tabStrip = $("#tabstrip").kendoTabStrip().data("kendoTabStrip");
tabStrip.remove("li:last");
I'm just stupid....
I looked some more at the code and I was leaving out the kendoTabStrip() word (bolded) from
$($("#tabstrip").kendoTabstrip().data("kendoTabStrip").items()[6]).attr("style","display:none")
i.e. Instead of (properly) having:
$($("#tabstrip").kendoTabStrip().data("kendoTabStrip").items()[6]).attr("style","display:none")
I had:
$($("#tabstrip").data("kendoTabStrip").items()[6]).attr("style","display:none")
Drew, thanks for your effort. Sometimes I just have to beat my head on a wall until I see what I've done.

jQuery - what does the newHeader property/field do?

I admit to being somewhat of a copy and paste JavaScript developer (with a strong background in other languages). I'm using the jQuery accordion, and using cookies to save the selected accordion section. I found some code which I integrated into my code. The key section is as follows.
change: function (event, ui) {
var index = $(this).find("h3").index(ui.newHeader[0]);
$.cookie(accordion, index);
}
This works, but I hate using code I don't understand. I understand that the index is discovered by using the find method (which makes the assumption that I don't have any h3s within the content), but what I don't understand is what the ui.newHeader[0] is doing. What is the newHeader array, and what is its purpose here?
Thanks,
Erick
Looking at the source for jquery.ui.accordion.js, it's just an object that contains the newly selected element.
You can see for yourself if you just check out the source:
// find elements to show and hide
var toShow = clicked.next(),
toHide = this.active.next(),
data = {
options: options,
newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
oldHeader: this.active,
newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
oldContent: toHide
},
down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
this.active = clickedIsActive ? $([]) : clicked;
this._toggle( toShow, toHide, data, clickedIsActive, down );
return;
},
newHeader is not an array, it's an object that represents the newly selected element. The code you posted finds all h3 elements in the accordion element, and then it takes the index of the newHeader. The element that newHeader represents changes each time the accordion changes.
It's exposed by the accordion widget. The newheader property holds the header of the activated element that the accordion opened.
See also the doc for the change event.

Categories