I have this script that is supposed to change the text of the button when the button is clicked.
<body>
<button onclick="toggleText(this);" id="id">Edit</button>
</body>
function toggleText(element){
var text = document.getElementById(element.id).textContent;
if (text == 'Edit') {
text = 'Done';
} else {
text = 'Edit';
}
}
But it doesn't work. It only works when you put document.getElementById(element.id).textContent directly into the if statements.
How do I get the variable to store properly?
Since you already get the element, you don't need to get it again. You can just use element.
But the reason why you can't change it is that you're only changing the variable that contains the text. It does not point to the element's properties. You need to use this:
function toggleText(element){
var text = element.textContent;
if (text == 'Edit') {
element.textContent = 'Done';
} else {
element.textContent = 'Edit';
}
}
When you access document.getElementById(element.id).textContent you get the value of it, not the reference. So changes to it won't affect the element.
But when you assign element to variable, it gets reference to it.
var element = document.getElementById(element.id);
if (element.textContent == 'Edit') {
element.textContent = 'Done';
} else {
element.textContent = 'Edit';
}
Just use:
index.js
var mainText = document.getElementById("mainText").value;
document.write(mainText);
index.html
<textarea id="mainText"></textarea>
As tymeJV commented, you can store by reference the element you get by id. Its property is stored by value. Instead store the element in a variable and access its property from the variable.
var text = document.getElementById(element.id);
if (text.textContent == 'Edit') {
text.textContent = 'Done';
} else {
text.textContent = 'Edit';
}
Is jquery an option ?
I used to do something like :
var a = $('#theid');
A.something
Related
I am trying to create searchable content with the help of some JS yet am having trouble hiding the content when there is no input in the search field.
Here is my script:
var $searchContainer = $("#search");
var $contentBoxes = $searchContainer.find(".content");
var $searchInput = $searchContainer.find("#search-input");
var $searchBtn = $searchContainer.find("#search-btn");
$searchBtn.on("click", searchContent);
$searchInput.on("input", searchContent);
while($searchInput == null) {
for($contentBoxes) {
hide();
}
}
function searchContent(){
var userInput;
//Check if call comes from button or input change
if($(this).is(":button")){
userInput = $(this).siblings("input").val();
} else {
userInput = $(this).val();
}
//make the input all lower case to make it compatible for searching
userInput = userInput.toLowerCase();
//Loop through all the content to find matches to the user input
$contentBoxes.each(function(){
var headerText = $(this).find(".title").text();
var contentText = $(this).find(".description").text();
//add the title and content of the contentbox to the searchable content, and make it lower case
var searchableContent = headerText + " " + contentText;
searchableContent = searchableContent.toLowerCase();
//hide content that doesn't match the user input
if(!searchableContent.includes(userInput)){
$(this).hide();
} else {
$(this).show();
}
});
};
I understand a while loop could have a condition where if userInput is equal to null it would loop through each content box and hide the element.
Something like this maybe?
while($searchInput == null) {
$contentBoxes.each(function(){
hide();
}
}
Any help would be greatly appreciated.
You would need to update your userInput variable every cycle of the loop because the userInput value never gets updated. Nonetheless this not a good way to do this because you will block your entire application.
There is no need for a loop, just use an if statement. Also, because this function gets executed when the value of the input is changed, there is no need to use this.
You could put this block of code beneath your $contentBoxes.each function:
$contentBoxes.each(function(){
var headerText = $(this).find(".title").text();
var contentText = $(this).find(".description").text();
//add the title and content of the contentbox to the searchable content, and make it lower case
var searchableContent = headerText + " " + contentText;
searchableContent = searchableContent.toLowerCase();
//hide content that doesn't match the user input
if(!searchableContent.includes(userInput)){
$(this).hide();
} else {
$(this).show();
}
});
if (userInput === null) {
$contentBoxes.each(function(){
$(this).hide();
});
}
I think it will be work like this. You just check if search input !== null and dont hide any content in this case
if($searchInput != null && !searchableContent.includes(userInput)){
$(this).hide();
} else {
$(this).show();
}
I've created a click to copy function so that users can click a button to copy the text content of another element. I've set this up so users can copy their serial number (which is generated dynamically from a shortcode - in Wordpress).
I had this working where the target container (that contains the text to be copied) was #copyTarget2 and the trigger button was #copyButton2. I then had this Javascript that was working:
<script>
document.getElementById("copyButton2").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("copyTarget2"), "msg");
});
document.getElementById("pasteTarget").addEventListener("mousedown", function() {
this.value = "";
});
function copyToClipboardMsg(elem, msgElem) {
var succeed = copyToClipboard(elem);
var msg;
if (!succeed) {
msg = "Copy not supported or blocked. Press Ctrl+c to copy."
} else {
msg = "Text copied to the clipboard."
}
if (typeof msgElem === "string") {
msgElem = document.getElementById(msgElem);
}
msgElem.innerHTML = msg;
setTimeout(function() {
msgElem.innerHTML = "";
}, 2000);
}
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
</script>
But now I've had to adjust the html so that I can dynamically display a 'NO VALID SERIAL NUMBER' message for any users who don't have an active serial number. This has meant that the element containing the text is different and is a child element of #copyTarget2.
What I need to know is:
Using the following screenshot from Console can anyone tell me the best way to keep the copy functionality and select the input container inside #copyTarget2?
I have already tried #copyTarget2 input, #copyTarget2.input to no avail.
Please bare in mind that my JS is using GetElementbyID() so simply replacing #copytarget2 with input[type="text"] won't work either.
change GetElementbyID to querySelector and try this selector
querySelector('input[name="_AFXSERIAL"]')
Either traverse the element you have by getElementsByTagName
document.getElementById('copyTarget2').getElementsByTagName('input')[0].value
or switch to querySelector
document.querySelector('#copyTarget2 input').value
If you want to experiment, you can try this Web API, https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent
This will help you remove the entire script you have written and will give you additional features as well like cut and paste.
Do check the compatibility chart though.
Also, putting the "#copyTarget2" to the input would have worked too.
DOM would have become,
<span>
<strong>
<input id="copyTarget2" />
</strong>
</span>
My onclick function won't fire unless it is clicked twice. I am very new to javascript but so far i trie moving around the var obj line, and changing the =="none" to "none"?"empty"; which are both things I didn't understand but saw other people did to fix this problem. Neither worked.
+
function showDiv(id){
var obj = document.getElementById(id);
if( obj.style.display == "none") {
obj.style.display='block'
}
else{
obj.style.display='none'
}
}
<div id="show1">
Roughly 2-3 months.
</div>
Your problem is, that you use the style property of the element directly. Assuming, that you did not set obj.style.display = "none"; in your code explicitly, the value remains undefined until the first click. After the first click it is set and everything works like you want it to.
To solve it use getComputedStyle() to access the element's style. This includes all styles set via CSS:
function showDiv(id){
var obj = document.getElementById(id),
compStyle = window.getComputedStyle( obj );
if( compStyle.display == "none") {
obj.style.display='block'
} else {
obj.style.display='none'
}
}
You should use strict equal operators to prevent from undefined style rule.
I would rather use addEventListener instead of onclick to keep my code cleaner, here is a jsfiddle with my version (some extras as dataset and triple conditional are there, but they are not necessarily needed in your example)
var showDiv = function (ev) {
var id = ev.currentTarget.dataset.id;
var obj = document.getElementById('show' + id);
obj.style.display = (obj.style.display === "none") ? 'block' : 'none';
};
http://jsfiddle.net/mindcookin/06nvkay7/4/
I have turned on allowedContent property in config.
config.allowedContent = "true"
This allows me to add ids to paragraphs inside contenteditable div.
However, now whenever I hit enter key inside the contenteditable div a new paragraph with same id is generated. I would assume after hiiting enter key a new paragraph should be inserted without any ids but it looks like the ids are copied from previously generated paragraph.
Is there any way to avoid this?
Try this. It's not bullet proof but works well enough. Even though I wrote it, I kind of hate it so if you improve on it, please share the love ;)
editor.on('key', function (evt) {
// Only if editor is not in source mode.
if (editor.mode === 'source') { return; }
// Enter is keyCode 13
if (evt.data.keyCode === 13) {
// if we call getStartElement too soon, we get the wrong element sometimes
setTimeout(function () {
var selection = editor.getSelection();
if (typeof selection === 'undefined') { return; }
var startElement = selection.getStartElement();
// If there are spans nested in the paragraph preserve them
// And we need to find the parent paragraph
// This could be optimized...
if (startElement.getName() == 'span') {
var text = "";
while (startElement.getName() == 'span') {
text += startElement.getHtml();
startElement = startElement.getParent();
}
if (text.length === 0) {
startElement.setHtml(' ');
} else {
startElement.setHtml(text);
}
}
// HERE I remove the "id" attribute.
startElement.removeAttribute("id");;
}, 10);
}
});
What is the correct way of addressing the id of an element in an if statement condition?
if($('id').val() == Reset)
var Submit_Status = $("#Reset").val();
else
var Submit_Status = $("#Nb_var97").val();
Thanks,
Neil P.
Since I can't see your HTML I'm going to post a simple example:
<div id="myID"></div>
if($("div").attr("id") == "myID")
{
//do stuff
}
if($('someSelector').attr('id') == 'Reset')
var Submit_Status = $("#Reset").val();
else
var Submit_Status = $("#Nb_var97").val();
if ( $('div').attr('id') == 'Reset' ) {
// do something
}
If you're trying to check the value of the ID property then you can get it using the attr method.
For example, if you were looping through all of the elements with the class foo and wanted to check for the id bar you could do this in your loops:
...
var id = item.attr("id");
if(id == 'bar')
{
}
Here's an example where all divs on the page are selected and each one has it's ID checked in turn:
var divs = $('div');
divs.each(function(index, value) {
var id = $(value).attr('id');
if(id == 'foo')
{
// Do foo work
}
else if(id == 'bar')
{
// Do bar work
}
Working example: http://jsfiddle.net/gZHMD/1/
Using a short form (ternary/conditional operator) instead of if
// element could be any html element but inputs have val and div, spans and suchlike don't have val
var Submit_Status = $('element').attr('id') == 'Reset' ? $("#Reset").val() : $("#Nb_var97").val();
Also, if you have multiple elements, then you have to select specific one, an example here.