I am making a simple web app. In one part of it, I have:
<ul class="sortable list-group">
<li id="firstTag" class="tags list-group-item">
<span id="present-count" class="badge"></span>
</li>
I have to access both the li element with id="firstTag" and the span element with id="present-count".
Anyhow, I am able to access only one, if I remove the id="firstTag", I am easily able to acess the span, anyhow, in presence of it, js gives the error: "cannot set property "innerHTML" of null" for the statement:
document.getElementById("present-count").innerHTML = something;
EDIT:
Both are being called in window.onload function with "firstTag" called before "present-count". See this fiddle: http://jsfiddle.net/poddarrishabh/2xzX6/3/
This is what I want the output to look like:
where both the "Present" text and the number can be changed.(I am using bootstrap).
$("#firstTag #present-count").html();
add jquery file to your page and try this
Sounds like you want to create a text node:
var textNode = document.createTextNode("first");
document.getElementById("firstTag").appendChild(textNode);
document.getElementById("present-count").innerHTML = "something";
Or to put the text before the span:
var textNode = document.createTextNode("first");
var present = document.getElementById("present-count");
present.innerHTML = "something";
document.getElementById("firstTag").insertBefore(textNode, present);
Here is an updated Fiddle.
If you are just trying to put some text before the present-count span, then just add another span and target that instead of the wrapping li:
<ul class="sortable list-group">
<li id="firstTag" class="tags list-group-item">
<span id="another-tag"></span>
<span id="present-count" class="badge"></span>
</li>
document.getElementById("another-tag").innerHTML = "some text";
document.getElementById("present-count").innerHTML = "some more text";
Try this code snippet
document.getElementById("firstTag").innerHTML = document
.getElementById("firstTag")
.innerHTML
+ "first";
document.getElementById("present-count").innerHTML ="something";
Hope it helps.
Try adding this
document.getElementById("firstTag").innerHTML ='<span id="present-count" class="badge">'
+ '</span>'
+ ' first';
document.getElementById("present-count").innerHTML = 'something';
DEMO
You were getting this error because with the first
document.getElementById("firstTag").innerHTML = "first"
you were replacing the <span>, and your DOM looked like
<ul class="sortable list-group">
<li id="firstTag" class="tags list-group-item">
first
</li>
</ul>
Then you couldnt find the element with id present-count because it wasnt there.
Related
I have a json string which contains HTML element. What I am trying to achieve is to fetch all anchor tag value <a> in that string.
Json String
"content" : "<p>Reference information</p> <ul> <li>My Url</li> <li>Your Url</li> </ul>"
Here is HTML Format
<p>Reference information</p>
<ul>
<li>My Url</li>
<li>Your Url</li>
</ul>
I have tried like this but cannot get exact value:
<div id="TestDiv" hidden >
</div>
let anchor = document.getElementById("TestDiv").getElementsByTagName("li");
anchor[0].innerHTML
I am getting this value
My Url
But I want to get https://myurl.com
another way I tried which was closed though still has problem but don't want to use regex:
content.match(/href="([^"]*?)"/);
How can I achieve that?
// Create an element
const el = document.createElement("div");
// set the inner HTML
el.innerHTML = `
<p>Reference information</p>
<ul>
<li>My Url</li>
<li>Your Url</li>
</ul>
`;
// grab all <a> tag
const nodeList = el.querySelectorAll("a");
// convert to array
const nodeArray = [...nodeList];
// map to href
const hrefs = nodeArray.map((a) => a.href); // ["https://myurl.com/", "https://yoururl.com/"]
You can use Array.prototype.map like:
var anchorUrls = Array.prototype.map.call(
document.anchors, (i) => i.href;
);
console.log(anchorUrls);
You can access the href attribute value using .href or using the getAttribute("href") method. However you are currently getting the li elements, but you want to instead get the anchor elements.
let anchor = document.getElementById("TestDiv").getElementsByTagName("a");
anchor[0].href;
To get all of the href's you will need to loop through the array of anchors.
var i;
for (i = 0; i < anchor.length; i++) {
anchor[i].href;
}
I am getting a response in a list from backend and putting error codes to a table as in picture
This explanation string has a URL in it as you see www.google... I want to make it clickable but I cannot.
When I try to replace the link with regex with following codes (my model object for the table item is response: errorArray.slice(1, errorArray.length));
const urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
const errorArray = errorResponse.error.toString()
.replace(/\[/g, "")
.replace(/]/g, "")
.replace(urlRegex, "<a href='$1' target='_blank' ></a>")
.replace(/\.,/g, ".")
this.allUploadedPinsFiles.push({uploadDate: uploaded, fileName: file.name,
status: status, responseHeader: errorArray[0], response: errorArray.slice(1, errorArray.length)});
It becomes
It is replacing item in the error array but in UI it still shows as a text. How can I make it that it can understand the link in a text and make it clickable?
and here is the html code for that list:
<div *ngIf="upload.response.length > 0">
<ul class="list-item">
<li *ngFor="let singleResponce of upload.response">{{singleResponce}}</li>
</ul>
</div>
Sanitize the data and pass to the html
this.sanitizer.bypassSecurityTrustHtml("<a href='www.google.com' target='_blank'>My Link</a>)
Try this
Working link
Use innerHtml
<li *ngFor="let singleResponce of upload.response">
<span [innerHtml]="singleResponce"
</li>
When I add a new button with some value it gets dynamically added into DOM. Non-Angular HTML element for this button is:
<li class="ui-state-default droppable ui-sortable-handle" id="element_98" data-value="2519">
25.19 EUR
<button type="button" class="btn btn-default removeParent">
<span class="glyphicon glyphicon-remove" aria-hidden="true">
</span>
</button>
</li>
Once I remove this button I want to check it is not present anymore. Element that I'm searching for is data-value="2519"and this could be anything I set, like for example 2000, 1000, 500, 1050,...
In page object file I have tried to use the following:
this.newValueButtonIsNotPresent = function(item) {
newValueButton = browser.element(by.id("containerQUICK_ADD_POINTS")).all(by.css('[data-value="' + item + '"]'));
return newValueButton.not.isPresent();
};
And in spec file I call this function as follows:
var twentyEurosButtonAttributeValue = '2000';
describe("....
it ("...
expect(predefined.newValueButtonIsNotPresent(twentyEurosButtonAttributeValue)).toBeTruthy();
I know this is not correct, but how I can achieve something like that or is there another way?
Stupid me, I found a simple solution. Instead dynamically locating an element I located the first on the list, which is always the one, which was newly added and then checked if it's text does not match:
Page object file:
this.newValueButtonIsNotPresent = function() {
newValueButton = browser.element(by.id("containerQUICK_ADD_POINTS")).all(by.tagName('li')).first();
return newValueButton.getText();
};
Spec file:
// verify element 20.00 EUR is not present
predefined.newValueButtonIsNotPresent().then(function(value) {
expect(value).not.toEqual(twentyEurosText);
});
What I've done is loaded some HTML from a file and I am attempting to modify some elements within that HTML.
The initialization looks like this:
var id = player_info["ID"];
$("#main_container").append(
$("<div />").attr({class: "player_container", id: "player_" + id}).css("display", "none")
);
// Add all information to the player container
var player_container = $("#player_" + id);
player_container.load("player_layout.html");
With player_layout.html looking like this:
<div class="player_name">
</div>
<div class="player_chips">
Chips:
<br/>
<span class='bidding'></span>/<span class='chips'></span>
</div>
<div class="player_stats">
Wins / Losses
<br/>
<span class="wins"></span>/<span class="losses"></span>(<span class="total_games"></span>)
<br/><br/>
Chips Won / Chips Lost
<br/>
<span class="chips_won"></span>/<span class="chips_lost"></span>
</div>
<button class="player_won">Player Has Won</button>
I then want to modify some of the elements, specifically classes. An example of the way I was initially doing this is:
player_container.find(".player_name").text(player_info['username']);
This wasn't working so I then tried to switch find with children and text with html but that didn't seem to work. I then tried this:
$('> .player_name', player_container).html(player_info['username']);
but that also didn't work. I understand that I can use DOM to grab the childNodes and compare the class names but there are a lot of classes that need modifying and I'd also like to know if this is possible in JQuery. Thanks in advance for any help.
You need to use complete callback method of .load()
var player_container = $("#player_" + id);
player_container.load("player_layout.html", function(){
player_container.find(".player_name").text(player_info['username']);
});
I am trying to clone a list item in the DOM and append it multiple times depending on the number of text values in the variable data using the each function. The problem is that all the new list items get the same text values (all list items are set equal to the last appended list item).
I suppose it has something to do with enclosures, but I cannot figure it out.
Can anyone explain what the problem is?
Thanks!
data:
var data = {"text1": ["text1_row1", "text1_row2"], "text2": ["text2_row1", "text2_row2"], "text3": ["text3_row1", "text3_row2"] }
HTML:
<ul>
<li id="entryTemplate" style="display:none">
<span class="text1"></span>
<span class="text2"></span>
<span class="text3"></span>
</li>
</ul>
Javascript:
function listData(data){
$.each(data.text1, function(i) {
var newDataRow = $('#entryTemplate').clone();
newDataRow.removeAttr('id')
.removeAttr('style')
.removeAttr('class')
.addClass('copy')
.appendTo('ul')
.find('.text1').text(data.text1[i])
.find('.text2').text(data.text2[i])
.find('.text3').text(data.text3[i]);
});
}
$.fn.clone = function(){
var ret = $();
this.each(function(){
ret.push(this.cloneNode(true))
});
return ret;
};
Desired HTML:
<ul>
<li id="entryTemplate" style="display:none">
<span class="text1"></span>
<span class="text2"></span>
<span class="text3"></span>
</li>
<li class="copy">
<span class="text1">text1_row1</span>
<span class="text2">text2_row1</span>
<span class="text3">text3_row1</span>
</li>
<li class="copy">
<span class="text1">text1_row2</span>
<span class="text2">text2_row2</span>
<span class="text3">text3_row2</span>
</li>
</ul>
Result I get (all li items get the text for row2):
<ul>
<li id="entryTemplate" style="display:none">
<span class="text1"></span>
<span class="text2"></span>
<span class="text3"></span>
</li>
<li class="copy">
<span class="text1">text1_row2</span>
<span class="text2">text2_row2</span>
<span class="text3">text3_row2</span>
</li>
<li class="copy">
<span class="text1">text1_row2</span>
<span class="text2">text2_row2</span>
<span class="text3">text3_row2</span>
</li>
</ul>
Your question is a bit foggy and it's not really clear what's the result you're looking for. Appart from that I saw something in your code that's probably causing it. Give it a try and let me know what happened.
When you do
$.each(data.text1, function(i) {
change it to
$.each(data.text1, function(pos, element) {
and replace your [ i ] for [element].
According to JQuery API, when doing an EACH loop, the 1st return is the position in the array and the second is the value itself.
UPDATED ANSWER:
Your data object variable is formatted wrong... It looks like you want each value of the data object to be an array (using curly brackets implies you are defining an object with keys), so you should be using square brackets []. See array vs array-like object
var data = {
"text1": ["text1_row1", "text1_row2"],
"text2": ["text2_row1", "text2_row2"],
"text3": ["text3_row1", "text3_row2"]
}
jQuery already has a clone method so you shouldn't need to override with your own.
Based on the data you provided, you want to be iterating over the data variable itself, not data.text1. Then you can get the text values by value of the current index (this is the second parameter passed to .each()) and referencing [0] and [1] to get the actual text
$.each(data,function(i,value){
console.log(value);
var newDataRow = $("#entryTemplate").clone();
newDataRow
.removeAttr('id')
.removeAttr('style')
.removeAttr('class')
.addClass('copy')
.appendTo('ul');
newDataRow.children('.text1').text(value[0]); // value[0] == data[i][0]
newDataRow.children('.text2').text(value[1]);
});