jQuery .is(":disabled") - Why doesn't this work? - javascript

http://jsfiddle.net/hw4bz89k/
Why doesn't the following return 'true'? I know I must be missing something elementary.
var test = $("#test");
test.prop("disabled", true);
alert(test.is(":disabled"));
#test {
width: 100px;
height: 50px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="test"></div>

You cannot disable a <div> element.
From the jQuery doc for :disable
The :disabled selector should only be used for selecting HTML elements that support the disabled attribute (<button>, <input>, <optgroup>, <option>, <select>, and <textarea>).

Related

How to set focus on an image on page load

Is there a way to set the focus on an on page load? I have found documentation stating to use the autofocus attribute but the documentation says that attribute only applies to input, button, textarea, and select.
Thanks.
You can try scrollIntoView method on window onload
window.onload=function(){
document.getElementById("ID_OF_IMAGE").scrollIntoView();
}
I think you looking for something like that:
window.addEventListener('load', function() {
document.querySelector(".classFromImage").focus();
})
What you could do is search for the img element with the autofocus attribute and set the focus after the DOM is read. You also need to set the tabindex to get that working.
I would only search for img[autofocus] so that you don't mess too much around with the default behavior.
window.addEventListener('DOMContentLoaded', function() {
let elm = document.querySelector("img[autofocus]")
if (elm) {
elm.focus()
}
})
img {
width: 100px;
height: 100px;
display: inline-block;
}
:focus {
border: 4px solid red;
}
<img autofocus tabindex="0">
You can focus a nonfocusable element by adding tabindex="0" attribute to the tag and use focus() method with js.
<img class="focusable" tabindex="0" src="#"/>
window.addEventListener('load', function() {
document.querySelector(".focusable").focus();
})

JQuery:Selecting second element in case element with same ID exists

I know it's not a good practice to use same id for different element , but in a case I am forced to use same id for two different elements ( which will be automatically generated in the original program)
I'm trying to select the second element with the same id ( or when scaling say , nth element ).
Is there a way to do this ?
I have created a code snippet here , that shows the problem.
$("#btn").click(function(){
$("#test").css("background","blue");
});
#test {
height: 100px;
width: 100px;
border: 1px solid #ccc;
margin:10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
</div>
<div id="test">
</div>
<button id="btn">Click Me</button>
You must not have duplicate ids but if you can not do that you can use Attribute Equals Selector [name=”value”] with :eq(index). The :eq takes the index of element of the collection. You may also want to use background-color.
Live Demo
$("[id=test]:eq(1)").css("background-color","blue");
Try using the data-id attribute instead since duplicate ids can produce unpredictable behaviour.
$("#btn").click(function(){
$("[data-id='test']:eq(1)").css("background","blue");
});
[data-id='test'] {
height: 100px;
width: 100px;
border: 1px solid #ccc;
margin:10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-id="test">
</div>
<div data-id="test">
</div>
<button id="btn">Click Me</button>
$("#test:eq(1)").css("background-color","blue");

Safe way to call a widget with namespace, with empty selector

The jQueryUi $.widget factory creates classes that can be used on two ways:
$("mySelector").myWidget(myOptions); and
$.myNamespace.myWidget(myOptions, mySelector).
The first way does not support namespace for widgets, so I prefer using the second version. My problem is that the version that support namespace throws an exception when mySelector doesn't match any html element (ie $(mySelector).length == 0). Is there any beautiful way to avoid this problem? I am developing an internal framework and would not like to have unnecessary if conditions.
For reference, I've already read (and I think I understood):
http://api.jqueryui.com/1.10/jQuery.widget/
http://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/
Both calls are not exactly the same. The first one will iterate through each elements of your selector and apply the widget, but not the second.
See:
$.ui.draggable('', 'div')
div {
width: 100px;
height: 100px;
border: solid black;
}
.ui-draggable {
border: solid blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<div>
</div>
<div>
</div>
To make it equivalent you'd need to use $.each, which would apply it to all of the elements in your selector and get rid of your error as well.
Like this for example:
$('div').each(function(){
$.ui.draggable('', this)
});
$('.empty').each(function(){
$.ui.draggable('', this)
});
div
{
width: 100px;
height: 100px;
border: solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<div>
</div>
<div>
</div>

Change CSS Property through JavaScript. (Uses ID's and Classes)

I'm trying to resize a panel using JavaScript to fit a small image into a panel, and struggling badly.
It's within the bold:
<body id="visCinemaTransRefund"><br>
<div id="content"><br>
<ul class="PayPanel" id="paymentDetails"><br>
Here's the CSS that needs modifying:
visCinemaTransRefund .PayPanel { width: 435px; }
How would I be able to modify with width of this panel?
I've also got a form I'm trying to resize within CSS:
visCinemaTransRefund FORM (width: 1005px;)
document.getElementById('paymentDetails').style.width = '1000px';
Have you tried using:
document.getElementById("paymentDetails").getElementsByClassName("PayPanel")[0].style.width="1000px"
Remember: getElementsByClassName return an array of elements, so using [0] you are indexing first element (and, of course, the only one).
Since getElementsById return a single elements, getElementsByClassName could be useless.
If you want to do this using CSS class :
HTML:
<div id="myDiv" class="medium"></div>
<button id="btn">Click me</button>
CSS:
#myDiv {
background-color: gray;
}
.medium {
height: 50px;
width: 50px;
}
.big {
height: 100px;
width: 100px;
}
JS:
document.getElementById("btn").onclick = function() {
var element = document.getElementById("myDiv"); // or document.getElementsByClassName("className")
if (element.className == "medium") {
document.getElementById("myDiv").className = "big";
} else {
document.getElementById("myDiv").className = "medium";
}
};
JSFIDDLE
Use the following code to change the width of tags by accessing HTML element from the DOM using getElement functions and setting width to it using setAttribute javaScript function.
document.getElementById("paymentDetails").setAttribute("style","width:500px;");
document.getElementById("visCinemaTransRefund").getElementsByTagName("form")[0].setAttribute("style","width:1000px;");
Using JavaScript:
document.getElementById('paymentDetails').style.width = '1000px';
Using JQuery:
$("paymentDetails").width(1000);
$("paymentDetails").css("width","1000px");

Placeholder for contenteditable div

I have the following: FIDDLE
The placeholder works fine and dandy until you type something, ctrl + A, and delete. If you do that, the placeholder disappears and never shows up again.
What's wrong? How can I have a placeholder for a contenteditable div?
HTML:
<div class="test" placeholder="Type something..." contenteditable="true"></div>
CSS:
.test {
width: 500px;
height: 70px;
background: #f5f5f5;
border: 1px solid #ddd;
padding: 5px;
}
.test[placeholder]:empty:before {
content: attr(placeholder);
color: #555;
}
Thanks.
While searching for the same problem I worked out a simple mixed css-JavaScript solution I'd like to share:
CSS:
[placeholder]:empty::before {
content: attr(placeholder);
color: #555;
}
[placeholder]:empty:focus::before {
content: "";
}
JavaScript:
jQuery(function($){
$("[contenteditable]").focusout(function(){
var element = $(this);
if (!element.text().trim().length) {
element.empty();
}
});
});
Updated fiddle
from Placeholder in contenteditable - focus event issue
[contenteditable=true]:empty:not(:focus):before{
content:attr(data-ph);
color:grey;
font-style:italic;
}
I got this solution from: https://codepen.io/flesler/pen/AEIFc
Basically put this css code:
[contenteditable=true]:empty:before{
content: attr(placeholder);
pointer-events: none;
display: block; /* For Firefox */
}
And have the placeholder attribute in your contenteditable div.
I've created a live demo: "Placeholder for content-editable divs", by HTML & CSS.
Also, Codepen: https://codepen.io/fritx/pen/NZpbqW
Ref: https://github.com/fritx/vue-at/issues/39#issuecomment-504412421
.editor {
border: solid 1px gray;
width: 300px;
height: 100px;
padding: 6px;
overflow: scroll;
}
[contenteditable][placeholder]:empty:before {
content: attr(placeholder);
position: absolute;
color: gray;
background-color: transparent;
}
<textarea class="editor"
placeholder="Textarea placeholder..."
></textarea>
<br/>
<br/>
<div class="editor"
contenteditable
placeholder="Div placeholder..."
oninput="if(this.innerHTML.trim()==='<br>')this.innerHTML=''"
></div>
I see what you mean. In your fiddle I typed in a few characters and deleted it using 'ctrl-a' and 'delete', and the placeholder reappeared.
However, it seems as if when you hit 'enter' within the contenteditabele div it creates a child div containing the line break <div><br></div> creating an issue with the :empty pseudo-class which only targets elements with no child elements.**
Check it out in chrome developer tools or whatever you use.
From developer.mozilla.org
The :empty pseudo-class represents any element that has no children at all. Only element nodes and text (including whitespace) are considered. Comments or processing instructions do not affect whether an element is considered empty or not.
Ctrl-a will delete the text, but leaves the child div. Might be able to fix this by adding some javascript.
some fixes:
1) $element.text().trim().length - it solved problems with <div><br/></div> and
2) data-placeholder attr instead of placeholder - it is true way
3) common selector $("[contenteditable]") - it is true way
4) display: inline-block; - fix for Chrome and Firefox
JavaScript:
jQuery(function($){
$("[contenteditable]").blur(function(){
var $element = $(this);
if ($element.html().length && !$element.text().trim().length) {
$element.empty();
}
});
});
HTML:
<div data-placeholder="Type something..." contenteditable="true"></div>
CSS:
[contenteditable]:empty:before {
content: attr(data-placeholder);
color: grey;
display: inline-block;
}
It feels like I am repeating myself, but why not to check contenteditable element mutations? Trying to bind everything to event that are changing content are pain in the butt. What if You need to add button (For example paste), or change content dynamically (javascript). My approach would be using MutationObservers. Demo fiddle
HTML:
<div class="test" id="test" placeholder="Type something..." contenteditable="true"></div>
CSS:
.test {
width: 500px;
height: 70px;
background: #f5f5f5;
border: 1px solid #ddd;
padding: 5px;
}
.test[placeholder]:empty:before {
content: attr(placeholder);
color: #555;
}
JavaScript:
var target = document.querySelector('#test');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (target.textContent == '') {
target.innerHTML = '';
}
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
Updating Christian Brink's answer, you could/should check for more events. You can do so by simply doing:
// More descriptive name
var $input = $(".placeholder");
function clearPlaceHolder() {
if ($input.text().length == 0) {
$input.empty();
}
}
// On each click
$input.keyup(clearPlaceHolder);
// Probably not needed, but just in case
$input.click(clearPlaceHolder);
// Copy/paste/cut events http://stackoverflow.com/q/17796731
$input.bind('input', (clearPlaceHolder));
// Other strange events (javascript modification of value?)
$input.change(clearPlaceHolder);
Finally, the updated JSFiddle
As swifft said, you can fix this with some super simple JS. Using jQuery:
var $input = $(".test");
$input.keyup(function () {
if ($input.text().length == 0) {
$input.empty();
}
});
On each keystroke it checks whether there's any input text present. If not, it whacks any child elements that may have been left behind by user interaction with the element -- e.g. the <div> swifft describes.
This solution worked for me. I'd converted this solution from angular to pure javaScript
In .html
<div placeholder="Write your message.." id="MyConteditableElement" onclick="clickedOnInput = true;" contenteditable class="form-control edit-box"></div>
In .css
.holder:before {
content: attr(placeholder);
color: lightgray;
display: block;
position:absolute;
font-family: "Campton", sans-serif;
}
in js.
clickedOnInput:boolean = false;
charactorCount:number = 0;
let charCount = document.getElementsByClassName('edit-box')[0];
if(charCount){
this.charactorCount = charCount.innerText.length;
}
if(charactorCount > 0 && clickedOnInput){
document.getElementById("MyConteditableElement").classList.add('holder');
}
if(charactorCount == 0 && !clickedOnInput){
document.getElementById("MyConteditableElement").classList.remove('holder');
}
getContent(innerText){
this.clickedOnInput = false;
}
I have this function, and I always use to prevent this kind of things.
I use my function in this way:
var notEmpty = {}
notEmpty.selector = ".no-empty-plz"
notEmpty.event = "focusout"
notEmpty.nonEmpty = "---"
neverEmpty(notEmpty)
And I just add the no-empty-plz to the Elements I that don't want to be empty.
/**
* Used to prevent a element have a empty content, made to be used
when we want to edit the content directly with the contenteditable=true
because when a element is completely empty, it disappears U_U
*
* #param selector
* #param event
* #param nonEmpty:
* String to be put instead empty
*/
function neverEmpty(params) {
var element = $(params.selector)
$(document).on(params.event, params.selector, function() {
var text = $(this).html()
text = hardTrim(text)
if ($.trim(text) == "") {
$(this).html(params.nonEmpty)
}
});
}
params is actually a json, so selector = params.selector as you can see
And hardTrim is also another fucntion I created is like a trim but includs &nbsp and <br/>, etc
function hardTrim(text) {
if (!exists(text)) {
return ""
}
text = text.replace(/^\&nbsp\;|<br?\>*/gi, "").replace(/\&nbsp\;|<br?\>$/gi, "").trim();
return text
}
This works for me and it's trim the long placeholder if the input is too small
[contenteditable="true"][placeholder]:empty:before {
content: attr(placeholder);
position: absolute;
left: 5px;
font-size: 13px;
color: #aaa;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
direction: ltr;
}
This happens because when you ctrl+A then delete, there is a <br> remaining in the innerHTML of the textarea. A simple jQuery/javascript solution can do the trick to empty out the textarea:
$(document).on('input','.test',function(){
if(this.innerHTML == '<br>'){
$(this).html('');
}
});
let contenteditableDiv = document.getElementById('contenteditableDiv');
contenteditableDiv.addEventListener('focus', function() {
let phs = this.querySelector('.placeholder-span');
if (phs != null) {
if (!this.hasOwnProperty('placeholderSpan')) {
this.placeholderSpan = phs;
}
phs.remove();
document.getSelection().setPosition(this, 0);
}
});
contenteditableDiv.addEventListener('focusout', function() {
if (this.textContent.trim().length == 0 && this.hasOwnProperty('placeholderSpan')) {
this.replaceChildren(this.placeholderSpan);
}
});
.placeholder-span {
opacity: 0.5;
}
<div id="contenteditableDiv" contenteditable="true"><span class="placeholder-span">Type something...</span></div>
And if You want to avoid contenteditable HTML formatting problems (leading/trailing spaces) and write it like a normal person:
<div id="contenteditableDiv" contenteditable="true">
<span class="placeholder-span">Type something...</span>
</div>
Then add:
window.addEventListener('load', function() {
let contenteditableDiv = document.getElementById('contenteditableDiv');
contenteditableDiv.innerHtml = contenteditableDiv.innerHtml.trim();
});
And if You want the placeholder to stay unitll there's input You need to put proper logic into mousedown, beforeinput and input event listeners.

Categories

Resources