Unable to get offset of an element - javascript

I am trying to get offset of some elements which is working fine for me. But the problem occurs if element id contains single quotes. It throw an error, e.g, if the element id is whats_next its working fine.
But if id is what's_next if gave me an error.
Error: Syntax error, unrecognized expression: #What's_Next
....value:null},t.error=function(e){throw new Error("Syntax error, unrecognized exp...
Also I don't have access over HTML I can not change the HTML. Do you guys have any solution for this ?
Here is my code:
$('.custom-toc li a').click(function(){
var id = $(this).attr('href');
console.log(id);
console.log($(id).offset());
});
HTML of element where I am clicking:
<a rel="internal" href="#What's_Next">What's Next</a>
HTML of element offset element:
<span id="What's_Next"></span>
<h4 class="editable">What's Next2</h4>

You can escape ' using replace()
HTML:
<div class="custom-toc">
<ul>
<li>
dddfs
</li>
</ul>
</div>
<span id="What's_Next">hello</span>
<h4 class="editable">What's Next2</h4>
JS :
$('.custom-toc li a').click(function(){
var id = $(this).attr('href').replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g,'\\$1');
console.log(id);
console.log($(id).offset());
});

Have you tried going for the id as attribute approach?
Like this:
var id = "What's Next";
var elem = $("span[id="+id+"]");
Well I tried, and it doesn't work :) - Cudos to Garvit, he has it right, this is his solution (only simplified):
var id = $(this).attr('href');
console.log(id);
id = id.replace("'","\\'");
console.log($("#"+id).offset());

Here's another way to do it without escaping the quote, although it requires you to remove the hash from the front of the href (and also, using $("*") is slow)
$('.custom-toc li a').click(function() {
var href = $(this).attr('href').substring(1);
var a = $("*").filter(
function(index) {
return $(this).attr('id') == href;
}
);
console.log($(a[0]).offset());

You can't use the ' symbol inside your div's id - You should change
<span id="What's_Next"></span>
to
<span id="Whats_Next"></span>
EDIT:
because You can't/don't want to change div's id You are working on an invalid code. You should consider debugging it first to further work.
EDIT 2:
Thanks to #Tibrogargan comment I've checked the w3c recommendation and he's probably right:
id = ID A unique identifier for the element. There must not be
multiple elements in a document that have the same id value. Any
string, with the following restrictions:
must be at least one character long
must not contain any space characters
Source: w3c.org

Related

Remove html element with javascript

When I press the Submit button if any error is generated then code create a span element.
My question is how I can clear the old error from the error container element, or if not possible then please sum up the errors.
$.each(err.responseJSON.errors, function (i, error) {
var el = $(document).find('[name="'+i+'"]');
el.after($('<span style="color: red;">'+error[0]+'</span>'));
});
I tried remove() but I cannot do it.
Thanks
you can remove the span with next().
next() finds the next sibling to the input field you are referring to.
it will give you the span:
el.next().remove();
you can use a class on the span f.e. class="validation-span"
el.next(".validation-span").remove();
this will make sure you only remove the span and no other element if existent :)
Add an span element after the input and set its HTML each time instead of using .after.
<input name="yourName">
<span class="errors"></span>
<script>
$(document).find('[name="'+i+'"] + .errors')
.html('<span style="color: red;">'+error[0]+'</span>');
</script>
I updated the both way you want, please pick which is more suitable to you
function logErrorCleanSpan(errorMessage){
$('#errorContainer').text(errorMessage);
}
logErrorCleanSpan("Hello");
logErrorCleanSpan("Jarvis");
function logErrorAppendSpan(errorMessage){
var span = $("<span>"+errorMessage+"</span>");
$('#errorContainerSpanAppend').append(span);
}
logErrorAppendSpan("1. Hello ");
logErrorAppendSpan("2. Jarvis ");
#errorContainerSpanAppend{
display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Append Error and clean the previous error<h3>
<span id="errorContainer"></span>
<h3>Append Error and keep the older one<h3>
<span id="errorContainerSpanAppend"></span>
Assign a id with index to span after each click remove previous span using id
Use jquery remove
$.each(err.responseJSON.errors, function (i, error) {
var el = $(document).find('[name="'+i+'"]');
el.after($('<span id="error'+i+'" style="color: red;">'+error[0]+'</span>'));
if($(document).find('span#error+i - 1+')) {
$( "span#error+i - 1+" ).remove();
}
});
this is just an example code not correct code.

jQuery background changing with id

here thisid stores the id of html element. and I want to change its background colour using the following code
let thisid = 'test';
$("a#" + thisid).css("background-color", "yellow");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a id="test" href="#">Hello world!</a><br/>
<a id="test2" href="#">Goodbye all</a>
this is not working, but it works if I remove thisid and write it in following way
$("a").css("background-color","yellow");
but it selects all with tag
below is what actually I want to do.
$(document).ready(function() {
// hide all questions
$("h1").hide();
// display first question
$("h1#1").show();
// show selected question
$("a").bind('click',function(){
let thisid = $(this).attr('id');
$("h1").hide();
$("h1#"+thisid).show();
$("a#"+thisid).css("background-color","yellow");
});
});
The argument to the jQuery function ($()) is being treated as a CSS selector. Since you're trying to find an element by ID, you need to start the selector with an octothorpe (#). Starting with a character selects by tag type. Not having your html handy, I'm guessing the actual problem is that the element with ID thisid is not an <a> tag. (You're actually selecting "any a tag with id thisid", but since an ID is unique including the tag type selector is redundant)
You should be able to do something more like this:
let thisid = "two"
$("#"+thisid).css("background-color","yellow");
thisid = "three"
// won't work, element with id `three` is not an 'a' tag
$("a#"+thisid).css("background-color","green");
thisid = "four"
$("div#"+thisid).css("background-color","blue");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="one">one</div>
<div id="two">two</div>
<div id="three">three</div>
<div id="four">four</div>

jQuery syntax error, unrecognised expression

syntax error, unrecognised expression: #2015-11-30|1112|1
I have an anchor tag with an Id of '2015-11-30|1112|1' that I would like to apply a class to. I am doing the same method for on a '' and this works, but I am getting syntax errors with the following. Can anyone explain the syntax error?
$(document).ready(function() {
$("#tbl_calendar").on("click", "a", null, clickAppointment);
});
function clickAppointment(eventData)
{
//Get the Id of the appointment that has been clicked:
currentAppointment = $(this).attr('id');
//alert('clicked' + '#'+currentAppointment)
$('#'+currentAppointment).addClass('selected');
}
You should escape the special chracters in your id using \\, check example bellow.
Hope this helps.
console.log( $("#2015-11-30\\|1112\\|1").text() );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="2015-11-30|1112|1">Div text example</div>
For your current code to work, you don't have to use that id selector since you already have the reference of the object inside the event function.
$(document).ready(function() {
$("#tbl_calendar").on("click", "a", clickAppointment);
function clickAppointment(eventData) {
//"this" will have a reference to the clicked object
$(this).addClass("selected");
}
});
Not sure about your HTML, but considering something similar to the below one.
<ul id="tbl_calendar">
<li>
<a id="2015-11-30|1112|1">Click</a>
</li>
</ul>
Working sample

jQuery, selecting just number from id like "article-23"

All right, I have a div tag which got a class="blog-post" and id like id="article-23" (where "23" could be any number, as it is id of blog post in a database). I need to somehow get just a number from that id and than apply some rules to that div tag. So say:
if number from id % 2 == 0 {
set text colour black to associated div tag with class of blog-post
} else {
set text colour white to associated div tag with class of blog-post
}
Thats just a "pseudo" code to show logic that I wan't to apply dependent if number from id is even or odd, but the question remains same, how do I just get number from id like "article-23" ?
As simple as
var number = "article-23".match(/\d+/)[0];
But you have to be sure that any digit exists in the string, otherwise you'd get a error.
You can actually apply rules via function, which makes this the cleanest solution (in my opinion):
$(".blog-post").css('color', function () {
return +this.id.replace('article-', '') % 2 ? 'blue' : 'red';
});
http://jsfiddle.net/ExplosionPIlls/Jrc5u/
Try this:
$('.blog-post[id^="article-"]').each(function () {
if (parseInt(this.id.replace('article-', '')) % 2 === 0) {
$('#' + this.id).css('color', 'black');
} else {
$('#' + this.id).css('color', 'white');
}
});
jsFiddle Demo
As an alternative, HTML5 supports these things called "data attributes", which are specifically meant for attaching data to your DOM without abusing things like the "class" or "id" attributes. jQuery provides a handy .data method for reading these attributes in a more obvious way.
You can add your own numeric ID attribute using something like "data-id":
<div class="blog-post" data-id="23" />
$("#blog-post").each(function () {
console.log($(this).data("id")); // Look up the data-id attribute
});
If I'm understanding correctly, you want the number after the hyphen of the id tag of your .blog-post class.
var article = $(".blog-post").attr('id'); //get the id
var article = article.split("-"); // split it on hyphens
return article = article[article.length-1]; // return the last element

How to get inner HTML of element inside a list item, within a delegate?

I have this bit of HTML :
<li eventId="123">
<img src="image.jpeg"/>
<h3 id="eventName">Event Name</h3>
<p id="eventDescription"></p>
</li>
I want to be able to pull out the <h3> and <p> via jQuery so that I can update their values.
I have a delegate bound to the list items, and on click I'm trying to grab hold of <h3> and <p> using :
function eventIdClicked()
{
// This gets hold of "123" OK
theEvent.id = $(this).get(0).getAttribute('eventId');
// How to get the other 2 inner html?
var existingEventName = $(this).get(1).getAttribute('eventName');
var existingEventDesc = $(this).get(2).getAttribute('eventDescription');
$.mobile.changePage("home.html");
}
Am I able to do this?
Maybe something like $(this).find("h3").text() and $(this).find("p").text()?
Very simple jquery.
Also, while it isn't affecting the code in this case, ID's must be unique.
If the ID's aren't unique the elements might as well not have id's.
First off, in your case you should use classes instead of Id's if there are going to be multiple eventnames and eventdescriptions. As for the event handling try passing the event object into the function like so:
function eventIdClicked(evt){
// Now you get get the event target.
// In your case this is the li element.
var target = $(evt.target);
// Now you can pull out the children that you want.
var eventName = target.children(".eventName").text();
var eventDescription = target.children(".eventDescription").text();
// Do more stuff...
}
First, I take for granted that there are several of these <li> so you shouldn't use the id attribute as id have to be unique. I replaced these with a class name.
<li eventId="123">
<img src="image.jpeg"/>
<h3 class="name">Event Name</h3>
<p class="description"></p>
</li>
I cleaned up your syntax using cleaner jQuery methods. I also add the values to the object your are already referencing.
function eventIdClicked()
{
theEvent.id = $(this).attr('eventId');
theEvent.name = $('.name', this).text();
theEvent.description= $('.description', this).text();
$.mobile.changePage("home.html");
}
If you are using HTML5 this would be cleaner:
Replace <li eventId="123">
with <li data-event="{'id':123,'name':Event Name','description':'Event Description'}">
Replace
theEvent.id = $(this).attr('eventId');
theEvent.name = $('.name', this).text();
theEvent.description= $('.description', this).text();
with theEvent = $(this).data('event');
function eventIdClicked()
{
// This gets hold of "123" OK
theEvent.id = $(this).get(0).getAttribute('eventId');
// since you used an id for both tags, you could even ommit the context
var existingEventName = $("#eventName", this);
var existingEventDesc = $("#eventDescription", this);
existingEventName.text("a new event name");
existingEventDesc.text("a new description");
$.mobile.changePage("home.html");
}
Use children function:
var existingEventName = $(this).children('h3')
var existingEventDesc = $(this).children('p');
Now you can use text to grab or modify values. On the other hand those elements also have ids so you can access them using id selector.
If you want to change the innerHTML of the <h3> and <p>, you could use
$('#eventName').html(/*NEW HTML HERE*/);
$('#eventDescription').html(/*NEW HTML HERE*/);
This is assuming the ids are unique in your document

Categories

Resources