How to Retrieve Values from a Class Within a Class Using JavaScript - html

I am not experienced with HTML and 'JavaScript', and is having a roadblock when attempting to check the values from a class.
Below is the source as seen from F12
I would like to retrieve all createdby text -muted values (as they may contain more than one row) to check if any of them matches SYSTEM, may I know how can it be done?
I understand that an image is not the best way to portrait my question, I will try to type the source in my question.
My apologies, and thank you.

You can get NodeList which contains createdby text-muted classes using document.querySelectorAll as follows.
const elems = document.querySelectorAll(".createdby .text-muted");
elems.forEach((item) => {
console.log(item.innerHTML); // This will contain the text value of the selected selector
});

Related

Need to get the 2sxc Field Type from an Entity

After getting everything working on this previous question Is there a way to Clone one or many Entities (records) in Code, I wanted to clean it up and make it more useful/reusable. So far, I am deciding how to copy/add the field using the content-type field names, so attribute.Key inside the foreach on Attributes. What I need instead is to know the Entity field's Type; meaning String, Number, Hyperlink, Entity, etc.
So I want something like if(AsEntity(original).FieldType == "HyperLink") { do this stuff }. I have explored the API docs but have not spotted how to get to the info. Is it possible?
I did figure out that the attribute.Value has a Type that I could use to answer most of them, but Hyperlink and String are both showing, System.String.
Here are, in order, String, Hyperlink, Entity, and Number:
atts: ToSic.Eav.Data.Attribute`1[System.String]
atts: ToSic.Eav.Data.Attribute`1[System.String]
atts: ToSic.Eav.Data.Attribute`1[ToSic.Eav.Data.EntityRelationship]
atts: ToSic.Eav.Data.Attribute`1[System.Nullable`1[System.Decimal]]
So is there a way from the Entity or its Attributes or some other pathway of object/methods/properties to just get the answer as the field Type name? Or is there a wrapper of some kind I can get to that will let me handle (convert to/from) Hyperlinks? I am open to other ideas. Since the fields.Add() is different by "FieldType" this would be really helpful.
It's kind of simple, but needs a bit more code because of the dynamic nature of Razor. Here's a sample code that should get you want you need:
#using System.Collections.Generic;
#using System.Linq;
#using ToSic.Eav.Data;
var type = AsEntity(Content).Type;
var attributes = type.Attributes as IEnumerable<IContentTypeAttribute>;
var typeOfAwards attributes.First(t => t.Name == "Awards").Type; // this will return "Entity"
I created a quick sample for you here: https://2sxc.org/dnn-tutorials/en/razor/data910/page

Should you rather define several or only one input parameter (with all values) for child components

I am faced with the question of how I should set up my Angular components with regard to inputs.
The first variant would be to create an input variable for each given value. This means that you would have to enter each variable individually when calling it:
The second variant would be to pack all the required values ​​in a model and only include this model. So in the end only one input:
Now I don't know which of the two variants is better suited for a large app with many components.
Is there one i should prefer from these two or are there more i dont know yet?
It depends upon your component info what info you are passing for example if the component is a shared button in which expected inputs could be button name, class, status etc.
In that scenario instead of passing all inputs separately you could go with one object lets say props which contains button properties.
export interface IButtonProps {
text: string;
class: string;
disabled?: boolean;
}
buttonData: IButtonProps;
this.buttonData = {
...this.buttonData,
text: 'Submit',
class: 'primary',
disabled: false
}
In template instead of passing individual input pass an object of buttonData
<my-button [props]="buttonData"></my-button>
Your example doesn't really explain itself too well but here goes:
If your input's are all of the same type and used for the same thing, theres nothing wrong with putting all of them in an array and passing them to the child.
Instead of:
[input]="'string1'" [input2]="'string2'" you could do [input]="['string1', 'string2']"
However consider this:
[iconClass]="'my-icon-class'" [buttonClass]="'my-button-class'"
Each of the inputs do something completely different, so putting them inside of an array would be very bad practice.
What you could also do is put all inputs in an object, for example:
input = { iconClass: 'my-icon-class', buttonClass: 'my-button-class' };
[input]="input"
You should only be using this, if the inputs are somehow related or/and do the same thing / modify the same element in the child.

StencilJs value does not exist on type 'Element'

I want to set the value of an ion-input field when the page is loaded.
I'm trying to get the element from the shadowDom using the shadowRoot querySelector.
It is a stencil project with ionic. The component uses the shadowDOM.
When I try to get the value my IDE says:
The nameEl:
const nameEl = this.el.shadowRoot.querySelector('#name');
The value will be set correctly, but I was wondering how I could fix this error message.
EDIT:
Answer as suggested by Ash is correct. And like Ash mentioned there are two ways of implementing this solution. But I was wondering if there is any difference between the solutions?
const nameEl = this.el.shadowRoot.querySelector('#name') as HTMLInputElement;
or
const nameEl: HTMLInputElement = this.el.shadowRoot.querySelector('#name');
EDIT:
The solution of course also work as one-liners as in Ash his example.
(this.el.shadowRoot.querySelector('#name') as HTMLInputElement).value
And in my case the input is a ionic input:
(this.el.shadowRoot.querySelector('#name') as HTMLIonInputElement).value
Setting the value works as you said but the reason for the error is as the message says Property 'value' does not exist on type 'Element'. To phrase it differently to help you understand, the message is saying:
You have something of type Element
The value property does not exist on the type definition for that something
Therefore you need to either correct the code to get the right type of element or in your case tell the code what to expect.
(<HTMLInputElement>nameEl).value
// OR
(nameEl as HTMLElement).value
The above snippets were taken from the related questions below and updated to match your variable names.
I answered here because you mentioned Stencil but is not related to the issues, however this question is a duplicate and answers for similar questions can be found at Property 'value' does not exist on type 'EventTarget' and Property 'value' does not exist on type EventTarget in TypeScript

Using selenium to access attribute text

I'm really new to selenium and this is probably really simple, but what i'm trying to do is store the '2017 League Table Ranking: 25th" text inside this attribute to a string in java:
<a href="/league-tables/rankings">
2017 League Table Ranking: 25th
</a>
public void findRanking() throws Exception {
String ranking = driver.findElement(By.xpath("(//a[contains(#href, '/league-tables/rankings')])")).getAttribute(href) ;
}
This gives me the link to the href that the attribute is using, and is the closest i've got to getting an output kind of right. I've tried simply getting the text of the element above, using the .getText() method but that returns nothing, where am i going wrong?
Since we now have a link to the page, I was able to create a unique locator. The problem was that there was more than one element that matched the locator and the first match wasn't the one you wanted. Since we don't need XPath here, I switched to a CSS selector. CSS selectors have better browser support, are faster, and I think are easier to create. This should work now.
public String findRanking() {
return driver.findElement(By.cssSelector("p.league-table-latest-rank > a[href='/league-tables/rankings']")).getText();
}
Here are some references for CSS selectors. I would suggest that you spend some time learning them. They are extremely powerful and should be your goto locator after By.id().
W3C CSS Selector Reference
Sauce Labs CSS Selector Tips
Original answer with XPath
.getText() should work on that element. It looks like you have an extra set of () in your XPath. Also, you should be able to use equals instead of contains(). There may be other links that contain that partial href that may be causing issues. I would try the below. I added a return and changed the return type to String.
public String findRanking() {
return driver.findElement(By.xpath("//a[#href='/league-tables/rankings']")).getText();
}
You can test your XPath in Chrome. Open the page and try $x("//a[#href='/league-tables/rankings']").length in the dev console and make sure it returns 1. If it's 0 then something is wrong with the locator. If it's > 1 then you'll have to further narrow the focus of your locator. Find a unique parent that has an ID or something unique.
Try this:
public String findRanking(){
WebElement e = driver.findElement(By.xpath("//a[contains(#href, '/league-tables/rankings')]");
return e.getText();
}
Try this way.
If you want to get the text of 2017 League Table Ranking: 25th then use below code.
String test = driver.findElement(By.xpath("//a[contains(text(), '2017 League Table Ranking: 25th')]")).getText();
System.out.println(test);
If you want to get the href attribute of this text 2017 League Table Ranking: 25th then use below code.
String href = driver.findElement(By.xpath("//a[contains(text(), '2017 League Table Ranking: 25th')]")).getAttribute("href");
System.out.println(href);

replace span class with other span class

It's kind of hard to explain. basically I want to change the span text in a class to the span text of another text in a chrome extension. The website code looks like this:
enter image description here
I want to change that 6 to the text of the other class that the 8 is in. I don't really know java that well so can someone please help.
EDIT:
I figured out how to change only that class but i still don't know how to get the text of the other class and change it to that. I was trying this:
document.getElementsByClassName('points').innerHTML
but it returned undefined.
The getElementsByClassName() function doesn't return just one item:
Returns an array-like object of all child elements which have all of the given class names.
Source: Document.getElementsByClassName()
I'm not too sure what your requirement is as the question is rather ambiguous. My assumption is that you would like the score and points to match for each score-wrapper section, like so:
var scoreWrappers = document.getElementsByClassName('score-wrapper');
[].forEach.call(scoreWrappers, function (scoreWrapper) {
var score = scoreWrapper.getElementsByClassName('score')[0];
var points = scoreWrapper.getElementsByClassName('points')[0];
score.innerText = points.innerText;
});