jQuery - Get <p> text by variable ID - javascript

Here is my code:
var itemCount = 0;
var addTo = "";
$(".add").click(function(){
alert($(this).attr('id'));
var itemClicked = $(this).attr('id');
var a = parseInt(itemClicked);
alert($(".price").find('#' + a).text());
itemCount = itemCount + 1;
});
and
<div class="col-sm-5 col-md-4 col-sm-2">
<div class="thumbnail">
<img src="..." alt="...">
<div class="caption">
<h3 class="item-header" id="1">iPhone</h3>
<p>...</p>
<p class="hidden" id="1">1</p>
<p class="price" id="1">19.95</p>
<p><button class="btn btn-primary add" role="button" id="1">Add to cart</button> More</p>
</div>
</div>
</div>
What I want to do is write a function takes figures out which button triggered the function, and retrieves the according price to the button. In this case I pressed 1, and I want the price according to Item 1.
When I perform alert(a); then I retrieve the number of 1. So I suppose something is wrong with the following line, just cant figure out what...
alert($(".price").find('#' + a).text());

Maybe you should add a data-price attribute (or something to reference to your actual data). I don't think it's a good practice to be dependant on the value of some paragraph tags. Better is to have a separation of display data and internal data.
You can access the data-price like this:
$('.button').click(function(e) {
console.log(e.target.getAttribute('data-price'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Shop</h1>
<p>iPhone 7</p>
<p>price € 110</p>
<button data-price="110" class="button">Add</button>

You don't need id:
$("button.add").click(function(){
var $card = $(this).parents("div.caption");
alert("adding good id:"+$card.children("input.good-id").val() + " with price: " + $card.children("p.price").text());
/* note - don't send price to backend,
it can be easily corrected in browser before click,
send only id of the good, and get price from DB */
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-5 col-md-4 col-sm-2">
<div class="thumbnail">
<img src="..." alt="...">
<div class="caption">
<h3 class="item-header">iPhone</h3>
<p>...</p>
<input type="hidden" class="good-id" name="goodId" value="1">
<p class="price">19.95</p>
<p><button class="btn btn-primary add" role="button">Add to cart</button> More</p>
</div>
</div>
</div>

I updated your html markup to use data attributes. In that way it will be easier for you to select the needed prices of certain items:
<p class="hidden" data-item="1">1</p>
<p class="price" data-price="1">19.95</p>
Demo:
$('.add').on('click', function() {
var itemId = $(this).attr('id');
var itemPrice = $('.price[data-price="'+ itemId +'"]').text();
alert(itemPrice);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-5 col-md-4 col-sm-2">
<div class="thumbnail">
<img src="..." alt="...">
<div class="caption">
<h3 class="item-header" id="1">iPhone</h3>
<p>...</p>
<p class="hidden" data-item="1">1</p>
<p class="price" data-price="1">19.95</p>
<p>
<button class="btn btn-primary add" role="button" id="1">Add to cart</button> More</p>
</div>
</div>
</div>

Related

if the class is active, reinstate the other with jquery

I want to update the comments of a post. Let's say the user has 2 comments, when he clicks edit I want to close the window of the other comment. In short, how can I keep one as "textarea" and the other as "span"?
$(document).on('click','.update-comment',function(e){
$('.active').removeClass('active');
let obj = $(this).closest('.comments');
let text = obj.find('.comment-text').attr('data-text');
obj.find('.ms-3').addClass('active');
if($('.ms-3').hasClass('active')){
$(obj.find('.comment-text')).replaceWith('<textarea id="updateComment">'+text+'</textarea>');
}else {
$(obj.find('.comment-text')).replaceWith('<span class="comment-text" data-text='+text+'>'+text+'</span>');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex py-2 comments" data-id="1">
<div class="flex-shrink-0">
<img src="https://via.placeholder.com/50" alt="..."/>
</div>
<div class="ms-3">
<div class="fw-bold">Name-1
<button type="submit" class="update-comment" data-id="1">Edit</button>
</div>
<span class="comment-text" data-text="Comment Example - 1" data-id="1">Comment Example - 1</span>
</div>
</div>
<hr>
<div class="d-flex py-2 comments" data-id="2">
<div class="flex-shrink-0">
<img src="https://via.placeholder.com/100" alt="..."/>
</div>
<div class="ms-3">
<div class="fw-bold">Name-2
<button type="submit" class="update-comment" data-id="2">Edit</button>
</div>
<span class="comment-text" data-text="Comment Example - 2" data-id="2">Comment Example - 2</span>
</div>
</div>
<hr>
Not trivial
I changed the button to type=button
I then removed the duplicate IDs and instead gave both span and textarea the class of comment-text
Then I changed the data-attr to just the .text() OR .val() depending on the element being a textarea or a span
I also cached several objects
$(document).on('click', '.update-comment', function(e) {
$allMS3 = $('.ms-3').removeClass('active');
let $thisMS3 = $(this).closest('.ms-3')
.addClass('active');
$allMS3.each(function() {
const $commentText = $(this).find('.comment-text')
let text = $commentText.is("span") ? $commentText.text() : $commentText.val();
if ($(this).hasClass('active')) {
$commentText.replaceWith('<textarea class="comment-text">' + text + '</textarea>');
} else {
$commentText.replaceWith('<span class="comment-text">' + text + '</span>');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="d-flex py-2 comments" data-id="1">
<div class="flex-shrink-0">
<img src="https://via.placeholder.com/50" alt="..." />
</div>
<div class="ms-3">
<div class="fw-bold">Name-1
<button type="button" class="update-comment" data-id="1">Edit</button>
</div>
<span class="comment-text" data-text="Comment Example - 1" data-id="1">Comment Example - 1</span>
</div>
</div>
<hr>
<div class="d-flex py-2 comments" data-id="2">
<div class="flex-shrink-0">
<img src="https://via.placeholder.com/100" alt="..." />
</div>
<div class="ms-3">
<div class="fw-bold">Name-2
<button type="button" class="update-comment" data-id="2">Edit</button>
</div>
<span class="comment-text" data-text="Comment Example - 2" data-id="2">Comment Example - 2</span>
</div>
</div>
<hr>

Reset where list items are moved to in an input field

It's midnight and this may not come across properly but I'll try..
I have two lists. One list of to-do items and the other of finished items.
I have an input field and button that adds items to the to-do list when clicked. - That all works fine.
I have a button that will move all items in the to-do list to the finished list. - That all works fine BUT when I do that and then type a new item to add it to the to-do list it now all gets added to the finished list.
I know that's where I'm now moving it to but I thought a return false would work but alas.
$ (function (){
$("#stillToDo").sortable({
connectWith: "#finished"
});
$("#finished").sortable({
connectWith: "#stillToDo"
});
$("#newItemBtn").click(function(){
let newInput = $("#newItem").val();
$("#stillToDo").append("<li>" + newInput + "</li>");
$("#newItem").val("");
$("#lastUpdated").text("Last updated " + Date());
})
$("#newItem").keypress(function(event){
let newInput = $("#newItem").val();
let keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13'){
$("#stillToDo").append("<li>" + newInput + "</li>");
$("#newItem").val("");
$("#lastUpdated").text("Last updated " + Date());
}
});
$("#allFinished").click (function(){
$("#finished").append($("#stillToDo"))
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sideBar">
<h2>D-B-To-Do</h2>
<div id="searchBar" class="input-group col">
<input class="form-control py-2" type="search" placeholder="Search your items " id="searchInput">
<span class="input-group-append">
<button class="btn btn-outline-secondary" type="button">
<i class="fa fa-search"></i>
</button>
</span>
</div>
<div class="days">
<h3>Monday</h3><hr>
</div>
<div class="days">
<h3>Tuesday</h3><hr>
</div>
<div class="days">
<h3>Wednesday</h3><hr>
</div>
<div class="days">
<h3>Thursday</h3><hr>
</div>
<div class="days">
<h3>Friday</h3><hr>
</div>
<div class="days">
<h3>Saturday</h3><hr>
</div>
<div class="days">
<h3>Sunday</h3><hr>
</div>
</div>
<div id="dayInfo" class="container col-6 row align-items-center dayInfo ">
<div class="card">
<img id="mondayImg" class="card-img-top" >
<div class="card-body">
<h3 class="card-title">Monday</h3>
<div id="subTitle" class="row">
<div class="col">
<h5>Still to do</h5>
<button id="allFinished" class="btn btn-success">Move all to finished</button><hr>
<ul id="stillToDo">
<li>test1</li>
</ul>
</div>
<div class="col">
<h5>Finished</h5><button id="allFinished" class="btn btn-danger">Remove finished</button><hr>
<ul id="finished">
<li>test2</li>
</ul>
</div>
</div>
<div id="newItemWrapper">
<input id="newItem" placeholder="Add a new item"><br>
<h6 id="newItemBtn" class="btn btn-success">Add new item</h6>
<p class="card-text"><small id="lastUpdated" class="text-muted">Last updated </small></p>
</div>
</div>
</div>
</div>
you are actually appending the full '#stillToDo ul' to the '#finished' that's why this weird behavior you are facing. . . just use this $("#finished").append($("#stillToDo").children()); everything will be ok. . .
$("#allFinished").click (function(){
$("#finished").append($("#stillToDo").children());
});
hope you get it and helped you.
For anyone wondering mindnight is not the best time to try and solve a problem...
Rather than moving the whole list over to the finished pile I just move the existing list items... Works perfectly now!

Increment a random number with a button?

I'm new to coding and I have the following problem:
I created a random number and I have it in a p tag which has a class, then I tried to increment this number by clicking on a button. This is my code so far:
$(document).ready(function(){
let films = JSON.parse(movies);
for (let i = 0; i < films.length; i++){
let movie = `
<div class="container">
<div class="poster">
<img class="pic" src="${films[i].image}">
</div>
<div class="text-box">
<div class="details">
<h2>${films[i].title}</h2>
<p>${films[i].releaseDate}</p>
<p>Genre: ${films[i].genre}</p>
<p>Director: ${films[i].director}</p>
</div>
<div class="like-box">
<input type="button" class="btn" value="Like 👍" number="${i}"></input>
<p class="counter"></p>
</div>
</div>
</div>
`;
$("#main2").append(movie);
$(".counter").text(Math.floor((Math.random()*100) + 1));
}
$(".btn").click(function() {
let el = parseInt($(".counter").text());
$(".counter").text(el+1);
})
});
The problem is, that if I click on the button instead of getting for example: 19 then after the click 20, what I get is 191919191920. So basically the button works, but not exactly how I want it to work. Can anybody help me please?
for (let i = 0; i < films.length; i++){
after this for loop is done, there will be films.length elements in dom with class counter.
and what this $(".counter").text() will return is concatenation of all text in elements with classes counter. That's why you got 191919191920.
Changes you would need to do:
Add new class to the container increaseing row count. This is mandatory to identify which movie you're on and increase the like value.
<div class='container row-" +i+ "'">
Then add onClick event to the like button to pass which row you're on. This is to identify which counter to increase the value.
<input type="button" class="btn" value="Like 👍" number="1" onclick="incrementLikes('row-" +i+ "')"></input>
$(document).ready(function() {
$(".counter").text(Math.floor((Math.random() * 100) + 1));
});
function incrementLikes(rowId) {
let mainRow = document.getElementsByClassName(rowId)[0];
let counter = parseInt(mainRow.getElementsByClassName('counter')[0].innerHTML);
mainRow.getElementsByClassName('counter')[0].innerHTML = counter + 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container row-1">
<div class="poster">
<img class="pic" src="">
</div>
<div class="text-box">
<div class="details">
<h2>Film Title 1</h2>
<p>13/06/2020</p>
<p>Genre: Action</p>
<p>Director: John Doe</p>
</div>
<div class="like-box">
<input type="button" class="btn" value="Like 👍" number="1" onclick="incrementLikes('row-1')"></input>
<p class="counter"></p>
</div>
</div>
</div>
<div class="container row-2">
<div class="poster">
<img class="pic" src="">
</div>
<div class="text-box">
<div class="details">
<h2>Film Title 2</h2>
<p>13/06/2020</p>
<p>Genre: Action</p>
<p>Director: John Doe</p>
</div>
<div class="like-box">
<input type="button" class="btn" value="Like 👍" number="1" onclick="incrementLikes('row-2')"></input>
<p class="counter"></p>
</div>
</div>
</div>
<div class="container row-3">
<div class="poster">
<img class="pic" src="">
</div>
<div class="text-box">
<div class="details">
<h2>Film Title 3</h2>
<p>13/06/2020</p>
<p>Genre: Action</p>
<p>Director: John Doe</p>
</div>
<div class="like-box">
<input type="button" class="btn" value="Like 👍" number="1" onclick="incrementLikes('row-3')"></input>
<p class="counter"></p>
</div>
</div>
</div>
The problem is your selector ".counter"
$(".counter").text returns the combined string value of all elements that have the class ".counter"
I have modified your code using selectors specific to the clicked button
let films = JSON.parse(movies);
for (let i = 0; i < films.length; i++){
let buttonId = "button" + i;
let movie = `
<div class="container">
<div class="poster">
<img class="pic" src="${films[i].image}">
</div>
<div class="text-box">
<div class="details">
<h2>${films[i].title}</h2>
<p>${films[i].releaseDate}</p>
<p>Genre: ${films[i].genre}</p>
<p>Director: ${films[i].director}</p>
</div>
<div class="like-box">
<input id="${buttonId}" type="button" class="btn" value="Like 👍" number="${i}"></input>
<p class="counter"></p>
</div>
</div>
</div>
`;
$("#main2").append(movie);
$("#${buttonId}.btn").next().text(Math.floor((Math.random()*100) + 1));
}
$("#${buttonId}.btn").click(function() {
let el = parseInt($("#${buttonId}.btn").next().text());
$("#${buttonId}.btn").next().text(el+1);
})

How to get the bootstrap title values dynamically on clicking with the respective footers?

Laravel View code:
<div class="col-sm-12">
#foreach($deviceCategory as $deviceCategories)
<div class="col-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<div class="col-sm-1">
<div id="deviceId" class="check">{{$deviceCategories-
>deviceCategoryId}}</div>
</div>
<br/>
</div>
<div class="panel-body">
<div class="col-sm-2">
<h5><strong>{{$deviceCategories->deviceCategoryName}}</strong></h5>
<h6><button style="border:none; background-color: transparent;"
disabled></button></h6>
</div>
<div class="col-sm-1" align="center">
<img src="{{asset(Storage::url('public/' . $deviceCategories-
>image))}}" width="200" height="150">
</div>
</div>
<div class="panel-footer" align="right"><a href="" data-
toggle="modal" data-target="#myModal"
class="getDeviceCategoryId">SELL THIS CATEGORY</a></div>
</div>
</div>
#endforeach
</div>
This is my view code. Here I am displaying the values dynamically that are fetched from db. Then When I click with the panel-footer (ie.,SELL THIS CATEGORY) , I need to alert the respective value in the panel-heading(ie.,{{$deviceCategories->deviceCategoryId}})
SCRIPT CODE
<script type="text/javascript">
$(document).ready(function() {
$('.getDeviceCategoryId').click(function() {
var value=$('#deviceId').text();
alert(value);
});
});
This is my script code I have tried. But I get only the first id value for all panel footers.
If I understand your question correct and you want to get particular <div id="deviceId"> text while click on SELL THIS CATEGORY:
Laravel View code:
<div id="deviceId" class="check">{{$deviceCategories->deviceCategoryId}}</div>
TO
<div id="deviceId" class="check device-{{$deviceCategories->deviceCategoryId}}">{{$deviceCategories->deviceCategoryId}}</div>
AND
<div class="panel-footer" align="right">SELL THIS CATEGORY</div>
TO
<div class="panel-footer" align="right">
SELL THIS CATEGORY
</div>
SCRIPT CODE
$(document).ready(function() {
$('.getDeviceCategoryId').click(function() {
var dataId = $(this).attr("data-id");
//if you use newer jQuery >= 1.4.3
//var dataId = $(this).data('id');
var value = $('.device-' + dataId).text();
alert(value);
});
});
UPDATE
SCRIPT CODE
$(document).ready(function() {
$('.getDeviceCategoryId').on('click', function() {
var dataId = $(this).attr("data-id");
//if you use newer jQuery >= 1.4.3
//var dataId = $(this).data('id');
var value = $('.device-' + dataId).text();
alert(value);
});
});
UPDATE
Your route should be like: Route::get('products/{dataId}','Categories#products')->name('products');
Your Laravel View code should be like:
<div class="col-sm-12">
#foreach($deviceCategory as $deviceCategories)
<div class="col-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<div class="col-sm-1">
<div id="deviceId" class="check">{{$deviceCategories->deviceCategoryId}}</div>
</div>
<br/>
</div>
<div class="panel-body">
<div class="col-sm-2">
<h5><strong>{{$deviceCategories->deviceCategoryName}}</strong></h5>
<h6><button style="border:none; background-color: transparent;" disabled></button></h6>
</div>
<div class="col-sm-1" align="center">
<img src="{{asset(Storage::url('public/' . $deviceCategories->image))}}" width="200" height="150">
</div>
</div>
<div class="panel-footer" align="right">SELL THIS CATEGORY</div>
</div>
</div>
#endforeach
</div>
Here no need JQ script...
Try this way -
<div class="panel-footer" align="right">
<a href="javascript:void(0)" data-deviceid="{{$deviceCategories-
>deviceCategoryId}}" data-toggle="modal" data-target="#myModal" class="getDeviceCategoryId">SELL THIS CATEGORY
</a>
</div>
and change your jQuery code to -
$(document).ready(function() {
$('.getDeviceCategoryId').click(function() {
var value=$(this).attr('data-deviceid');
alert(value);
});
});

javascript doesn't work in all elements of foreach MVC

i build a code for comments and replies of them.. i use a #foreachto show all elements in ViewBag which have a list of comments..
every thing works fine in post and get ..
but my problem it's when i try to make "submit"button of replies disable to prevent anyone from pressing it without typing..
so i use javascript but the code didn't work fine ..
first it work only with the last element of #foreach .. after i use the name as "class" instead of "id" it work for all elements
but the problem is .. if i typing in first reply input text for example .. the button didn't enable .. but if i typing at last reply input text .. all buttons enable ..
I want the code work for each reply .. only when some one typing in that input text ..
JavaScript
<script>
var $inputreply = $('.replies');
var $buttonreply = $('.replysubmit');
setInterval(function () {
if ($inputreply.val().length > 0) {
$buttonreply.prop('disabled', false);
}
else {
$buttonreply.prop('disabled', true);
}
}, 100);
</script>
View which have loop #foreachof comments and replies for each comment
<section class="comment-list">
#foreach (var item in ViewBag.CommentsList)
{
<article class="row">
<div class="col-md-10 col-sm-10">
<div class="panel panel-default arrow left">
<div class="panel-body">
<header class="text-left" style="direction:rtl;">
<time class="comment-date" datetime="16-12-2014 01:05"><i class="fa fa-clock-o"></i> #item.CommentDateTime</time>
</header>
<div class="comment-post">
<p>#item.Comment</p>
</div>
<p class="text-right"><a class="btn btn-default btn-sm replybtn"><i class="fa fa-reply"></i> reply</a></p>
</div>
</div>
<!--ReplyBox-->
#if (Request.IsAuthenticated)
{
using (Html.BeginForm("Reply", "Home", new { #id = #item.PostID, #commentId = #item.ID }, FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="input-group" style="direction:ltr;">
<input type="text" class="replies form-control" placeholder="" name="replies" />
<span class="input-group-btn">
<button class="replysubmit btn btn-primary" type="submit">Reply</button>
</span>
</div>
}
}
else
{
<div class="form-horizontal">
<div class="alert alert-danger replybox" style="display:none;">
<span>please login to reply</span>
</div>
</div>
}
#foreach (var subitem in ViewBag.Relies)
{
if (#subitem.CommentID == #item.ID)
{
<article class="row">
<div class="col-md-9 col-sm-9">
<div class="panel panel-default arrow left">
<div class="panel-heading left">Reply</div>
<div class="panel-body">
<header class="text-left">
<time class="comment-date" datetime="16-12-2014 01:05"><i class="fa fa-clock-o"></i> #subitem.ReplyDate</time>
</header>
<div class="comment-post">
<p>#subitem.CommentReply</p>
</div>
</div>
</div>
</div>
<div class="col-md-2 col-sm-2 col-md-offset-1 col-sm-offset-0 hidden-xs">
<figure class="thumbnail">
<img class="img-responsive" src="http://www.keita-gaming.com/assets/profile/default-avatar-c5d8ec086224cb6fc4e395f4ba3018c2.jpg" />
<figcaption class="text-center">#subitem.UserName</figcaption>
</figure>
</div>
</article>
}
}
</div>
<div class="col-md-2 col-sm-2 hidden-xs">
<figure class="thumbnail">
<img class="img-responsive" src="http://www.keita-gaming.com/assets/profile/default-avatar-c5d8ec086224cb6fc4e395f4ba3018c2.jpg" />
<figcaption class="text-center">#item.userName</figcaption>
</figure>
</div>
</article>
<br />
}
</section>
The selector $('.replysubmit') returns all the items with that css class, hence updating the disabled property of all those elements, not just the one closest to the input element.
You should use a relative selector to get the submit button inside the form where the reply input element is.
jQuery closest() and find() methods will be handy
This should work
$(function () {
$('.replysubmit').prop('disabled', true); // Disable all buttons when page loads
// On the keyup event, disable or enable the buttons based on input
$(".replies").keyup(function() {
if ($(this).val().length > 0) {
$(this).closest("form").find(".replysubmit").prop('disabled', false);
} else {
$(this).closest("form").find(".replysubmit").prop('disabled', true);
}
});
});

Categories