Uncaught TypeError on second onclick event using this.innerHTML - typeerror

Everyone, I have a rather weird problem.
In an HMTL unordened list I have several list elements with onClick events, and they all call the same function.
<ul>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">1</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">2</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">3</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">4</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">5</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">6</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">7</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">8</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">9</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">0</li>
</ul>
This is the Javascript function:
function show(ID){
show = document.getElementById(ID);
notShow = document.getElementsByClassName("visible")[0];
if (typeof notShow !== "undefined"){
notShow.classList.toggle("hidden");
notShow.classList.toggle("visible");
}
show.classList.toggle("hidden");
show.classList.toggle("visible");
}
for some unknown reason, the function works fine when I click one of the <li> elements first, but the second time I do that I get an error:
Uncaught TypeError: object is not a function ACNL.php:31
I think the error is not inside the javaScript function, but in the HTML-element that calls the function.
Any help would be appreciated!

I see a few problems here. In no particular order:
It would probably be safest to change the inner variable name show to something else since your function is also called show(...).
Declare variables with the var keyword to avoid populating the top namespace.
You're retrieving DOM elements by ID, but none of your DOM elements (in the above example) have ID attributes. You'll want to add them to your li items at least, e.g. id="1"
If these elements don't have visible to start off with, you'll add both visible and hidden when you "toggle".
If you toggle visible and hidden on the li items, then notShow = document.getElementsByClassName("visible")[0]; should probably change, as you will be retrieving the li items once they have visible in them. Try using other class names or element types.
Here is a jsFiddle to get you started (ignore the window.show definition that's specific to jsFiddle).

Related

Is it possible to not omit some opts on the outermost element in a custom Riot tag?

I'm using RiotJS v3.9
I've written a custom tag that accepts a few opts. The problem is that the markup it generates includes all of those opts on the outermost element, in addition to the interior tags where I explicitly deposit them. I do not want any opts to appear on the top element unless I make that happen.
In this case, my custom tag display a list of items. One of the opts it accepts is the value for a specific data- attribute on each list item. So, I want data-something={opts.itemSomething} to appear on each list item, but I do not want that to appear on the wrapper.
// my-list.tag
<my-list>
<ul data-something={ opts.something }>
<li
each={ item in opts.items }
data-something={ parent.opts.itemSomething }
>
{ item }
</li>
</ul>
</my-list>
Using it:
<my-app>
<my-list
something="parent-value"
item-something="child-value"
items={['one', 'two', 'three']}
/>
</my-app>
What it emits into the page:
<my-list something="parent-value" item-something="child-value">
<ul data-something="parent-value">
<li data-something="child-value"> one </li>
<li data-something="child-value"> two </li>
<li data-something="child-value"> three </li>
</ul>
</my-list>
I don't want the emitted <my-list> tag to have either the parent-value or the child-value on it. I only want those attributes to appear on the <ul> and <li>, like I coded it.
// bad output
<my-list something="parent-value" item-something="child-value">
// good output
<my-list>
Is this possible?
Also, I know from working with React that I'm likely to encounter future cases where I want some of the opts to appear on the wrapper while hiding others. So, ideally I'd like to know how to control this behavior on a per-opt basis.
you can remove the unwanted attributes in both the "updated" and "mount" event.
check this demo
However I strongly suggest you to switch to riot#5!!

How can I get css property of an element which clicked in Blazor?

Here is some A elements in blazor server-side:
<div>
<a href="javascript:void(0)" class="Add" #onclick="SingleAddClick">
<a href="javascript:void(0)" class="Add" #onclick="SingleAddClick">
<a href="javascript:void(0)" class="Add" #onclick="SingleAddClick">
<a href="javascript:void(0)" class="Add" #onclick="SingleAddClick">
<a href="javascript:void(0)" class="Add" #onclick="SingleAddClick">
</div>
All the position of the A elements above is absolute. The Left and Top are differing from each A element.
Now when an A element is clicked, I wanna get the Left and Top of its position.
I need to transfer the js object from .Net method to JS method by JS interop while I don't know how to get the JS object in .Net method.
How can I achieve this?
Thank you.
You can capture a reference to your element as follows:
<a #ref="anchorElement" href="javascript:void(0)" class="Add"
#onclick="SingleAddClick">
#code
{
private ElementReference anchorElement;
}
Now you can call a JSInterop method and pass it the element reference. You should use it in your JS method as though it was retrieved by the getElementById method.
Note: You shouldn't use JavaScript in Blazor. Use #onclick:preventDefault instead of href="javascript:void(0)"
I hope that helps! If you get stuck, let me know
In-order to identify left and top, you'll need to provide a unique identifier (uid) to your every anchor tags. Your uid can either be a ElementReference or a just static (hard-coded) name. With this uid you can identity from where the event is raised from then search it in dom to find relative position to the viewport.
Below are the changes you will need to do to get the elements left and top position.
Razor Component
#inject IJSRuntime JSRuntime // need to inject IJSRuntime to invoke a JavaScript function.
<a id="anchor1" href="" class="Add" #onclick='() => SingleAddClick("anchor1")' #onclick:preventDefault>
#code{
private async Task SingleAddClick(string clickedElementId)
{
//your existing code
// call the javacript method that will be returing something.
var dimensions = await JSRuntime.InvokeAsync<string>("getDimensions", clickedElementId);
// I've used a dynamic type object so that I don't need to create a custom class to desealize it.
dynamic d = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(dimensions);
// Since I've used dynamic keyword thus the type will get resolved at runtime.
// Will throw exception if d is null thus need to be handled properly.
string top = d.top;
string left = d.left;
}
}
JS Library
If you are using any existing js file for interop service then add below javascript method else create a new js file and reference it in _host.
function getDimensions(element) {
return JSON.stringify(document.getElementById(element).getBoundingClientRect());
}
Note: The getBoundingClientRect() method returns the size of an element and its position relative to the viewport.

How to render the value of v-for based on the condition(v-if) provided in vue.js

I'm trying to implement the condition provided in the code. My last attempt was like in the one in the code.
<ul class = "details" v-for = "(value, propertyName) in items[this.index]" :key = "value.id">
<li v-if="{{propertyName}} == 'IndustryIdentifiers'">Data not available</li>
<li v-else>{{value}}</li>
</ul>
How can the following be implemented:
v-if="{{propertyName}} == 'IndustryIdentifiers'"
The {{ }} syntax is used to wrap a JavaScript expression that should be output as text. It isn't necessary to use the braces to access data in other contexts. In the case of a v-if the attribute value is already an expression and there's no need to include any special characters to pull in data values.
So it'd be just v-if="propertyName === 'IndustryIdentifiers'":
<ul class="details" v-for="(value, propertyName) in items[this.index]" :key = "value.id">
<li v-if="propertyName === 'IndustryIdentifiers'">Data not available</li>
<li v-else>{{ value }}</li>
</ul>
Here I'm assuming that item[this.index] is an object rather than an array, which is implied by the way you've written your loop.
You could also write it like this:
<ul class="details" v-for="(value, propertyName) in items[this.index]" :key = "value.id">
<li>{{ propertyName === 'IndustryIdentifiers' ? 'Data not available' : value }}</li>
</ul>
You should also be able to remove the this. from the index unless it's also declared locally.
I also wonder whether you're intentionally creating a separate list for each value, with each list only containing a single item. Difficult to know exactly what you're trying to achieve but I would guess that you want the loop inside the <ul> rather than on the <ul>. If you only have a single <li> (as in my second example) then you could move the v-for onto the <li>. If you want to stick to having two <li> elements with v-if/v-else then you'll need to wrap them in a <template> tag to hold the v-for.

Mouse pointer/cursor pointing to webelement apart from Actions class in Selenium

I am well aware that we can use Actions class to move to a particular web element as below.
Actions(driver).moveToElement(driver.findElement(By.xpath("element"))).build().perform();
For one of the webelement as soon as I move to that element I should get a dropdown. But some times this is working and some times not. Is there any option other than Actions class to simulate mouse movement to particular webelement?
The HTML code for the element I am trying to simulate mouse pointer movement to it is one with class="dropdown-submenu"
<li ng-show="setStatusPermission" class="dropdown-submenu">Set status
<ul class="dropdown-menu" role="menu">
<li ng-show="activePermission" class="">Active</li>
<li ng-show="cancelPermission" class="">Cancelled</li>
<li ng-show="completePermission" class="ng-hide">Completed</li>
<li ng-show="errorPermission" class="ng-hide">Error</li>
<li ng-show="expiredPermission" class="ng-hide">Expired</li>
<li ng-show="suspendPermission" class="ng-hide">Suspended</li>
</ul>
</li>
Automation code snipet to perform the operations is as below.
WebElement webElementSetStatus = basePage.waitForElementToLoadAndReturnWebElement_BasePage(
bc_ui_TaskAction_Setstatus, "linkText", "15");
basePage.getActions_BasePage().moveToElement(webElementSetStatus).build().perform();
List<WebElement> options = basePage.getWebElements_BasePage(
"#bc-td-actions-dropdown-list > li.dropdown-submenu > ul > li", "cssSelector");
for (WebElement option : options)
if (!option.getAttribute("class").equals("ng-hide") && !option.getText().isEmpty())
actualAvailableStatusOptions.add(option.getText());

Robot Framework selecting from UL ID and li class

I am unable to select any of the ul id / li class items. I do not see a method for handling this. Anyone able to get it done?
<ul id="game_list">
<li class="game_link" onclick="update_blurb('one');">ONE</li>
<li class="game_link" onclick="update_blurb('two');">TWO</li>
<li class="game_link" onclick="update_blurb('three');">THREE</li>
<li class="game_link" onclick="update_blurb('four');">FOUR</li>
<li class="game_link" onclick="update_blurb('five');">FIVE</li>
<li class="game_link" onclick="update_blurb('six');">SIX</li>
</ul>
I am attempting to select the li class links.
I'm still not exactly sure what is the problem. The right method to click on things is Click Element. You can select any of the <li> elements by a CSS selector or an XPath expression (documentation, see "Locating elements").
For example:
Click Element | css=#game_list > li:nth-child(3)
clicks the third <li> element.
Or by text:
Click Element | xpath=id('game_list')/li[text()='THREE']
selects the <li> element whose text is "THREE".
Figured this out.
I create my own element id and click that new id.
Example:
Assign Id To Element xpath=//li[#onclick="update_blurb('one');"] one
Click Element one
Thanks for checking it out, Slanec.