I'm making a shopping cart for multiple items in a database but after adding a textbox and adding var quantity the code only understands the first textbox and adds that quantity for all the other add to cart links.
How do I tell the program to find a specific textbox based on the item it is associated with, just like the line below it that finds the item based on the 'data-id'.
I've tried using $(".qty-txt").children().value() but I still don't know how to specify which Anchor tag to find.
<script type="text/javascript">
$(function () {
$(".AddLink").click(function () {
var quantity = $("#qty").val();
var recordToAdd = $(this).attr("data-id");
if (recordToAdd != '') {
$.post("/ShoppingCart/AddToCart", { "id": recordToAdd, "qty": quantity },
function (data) {
$('#cart-status').text(data.CartCount);
});
}
});
});
</script>
The first 3 lines are my Texbox in the anchor tag (would prefer not to use anchor tag if possible)
The second anchor tag is my Link to Add to cart.
<a class="qty-txt" data-id="#item.ID">
#Html.TextBox("Quantity", 1, new { #class = "qty-input", #id = "qty", size = 1 })
</a>
<a href="#" class="AddLink" data-id="#item.ID" data-toggle="modal" data-target="#myModal">
Add to cart
</a>
You generating invalid html by including duplicate id attributes using
#Html.TextBox("Quantity", 1, new { #class = "qty-input", #id = "qty", size = 1 })
And var quantity = $("#qty").val(); will only ever return the value of the first element with id="qty"
You need to use new { id = "", ...} to remove the id attribute or just create the textbox manually using
<input type="text" class="qty-input" size = "1" value="1" />
Then wrap the textbox and the "Add to cart" link in a container so you can use relative selectors (not sure why you wrap the textbox in another <a> tag?)
<div class="product">
<input type="text" class="qty-input" size = "1" value="1" />
Add to cart
</div>
The modify the script to
$('.AddLink').click(function () {
var quantity = $(this).closest('.product').find('.qty-input').val();
var recordToAdd = $(this).data('id'); // correct usage to access data- attributes
if (recordToAdd != '') { // not sure why you need this (why would it ever be null?)
$.post("/ShoppingCart/AddToCart", { "id": recordToAdd, "qty": quantity }, function (data) {
$('#cart-status').text(data.CartCount);
});
}
});
Just select $(".qty-input") to get all the matching inputs. Otherwise, you're selecting the list of wrapper elements...if you went that way, then you need to navigate using loops on each instance of the wrapper object(s).
Related
I am trying to create an extention which clicks on an item of the price given by the user. Here is the relevant popup.html:
<input style="display:none" /><input type="text" id="userInput" value='' />
<button id="clickme">Run</button>
When 'clickme' is clicked, it runs this popup.js:
document.getElementById('clickme').addEventListener('click', function() {
var price = '$'+ document.getElementById("userInput").value+".00";
alert(price);
$("p:contains("price")").parentNode.click();
});
If you type the desired price in in the form as 48, it returns an alert with the value $48.00.
It then shuold click on the item of that price, however this currently isn't working. Here is the code of the relevant part of the website which I am trying to run my extention on (not my website):
<div class="grid__item wide--one-fifth large--one-quarter medium-down--one-half">
<a href="/collections/1seventeenweek7/products/copy-of-supreme-dazzle-warm- up-top-red" class="grid-link text-center">
<p class="grid-link__title">Supreme Corner Cap Light Blue</p>
<p class="grid-link__meta">
<span class="visually-hidden">Regular price</span>
$48.00
</p>
</a>
</div>
I am trying to get it to search for the p element containing $48.00, and then click on the a element which is the parent element, but this is not currently working. What am I doing wrong? - thanks
Here you go. This will work!
document.getElementById('clickme').addEventListener('click', function() {
var price = '$'+document.getElementById('userInput').value+'.00'
var metas = document.getElementsByClassName('grid-link__meta')
alert(price)
for (let i = 0; i < metas.length; i++) {
if (metas[i].innerHTML.includes(price)) metas[i].parentNode.click()
break
}
})
Personally, I'd really like to use something like the following, yet I forgot that getElementsByClassName doesn't return an array, but rather a NodeList object.
var price = '$'+document.getElementById('userInput').value+'.00'
var metas = document.getElementsByClassName('grid-link__meta')
var match = metas.find((curr) => curr.innerHTML.includes(price))
match.parentNode.click()
Here in the code there is ajax which assigning the values to the fields but there is the edit icon which is created dynamically it means that how many address you added in the database then number of times edit icon will be created. My need is that when I click on first button then it will alert its id value and when I clicked on the other one then it will alert its id value
Following is my code I tried:-
var full_url = document.URL; // Get current url
var url_array = full_url.split('=') // Split the string into an array with / as separator
var UserId = url_array[url_array.length-1]; // Get the last part of the array (-1)
$.ajax({
url:"url,
type: "GET",
dataType: 'json',
async: false,
data:{"UserId":UserId},
success: function(response){
if (response.response.total_record[0].status === "active") {
$('#email').html(response.response.total_record[0].email);
$('#name').html(response.response.total_record[0].first_name+" "+response.response.total_record[0].last_name);
$('#first').val(response.response.total_record[0].first_name);
$('#last').val(response.response.total_record[0].last_name);
$('#phone').val(response.response.total_record[0].phone_number);
$('#alternative').val(response.response.total_record[0].alternative_number);
$('#id').val(response.response.total_record[0]._id);
$('#status').val(response.response.total_record[0].status)
if (response.response.total_record[0].status === "active") {
$('#activate').hide();
}
if (response.response.total_record[0].status === "deactivate") { $('#activate').show();
$("#deactivate").hide();
}
$.each(response.response.total_record[0].address,function(i,item){
console.log(response.response.total_record[0].address[i])
$('#edit_id').val(response.response.total_record[0].address[i]._id)
$('.cards').append('<div class="location-list"><header class="header_title"><div class="location_heading"><h3>Location:</h3></div><div class="edit_icon"><a class="editByAnchor" id='+response.response.total_record[0].address[i]._id+' href="#" data-toggle="modal" data-target="#edit_address"><i class="fa fa-edit"></i></a></div></header><div id="dAddress" class="location-detial"><p><span id='+response.response.total_record[0].address[i]._id+'>'+response.response.total_record[0].address[i].address+'</span></p></div></div>');
});
}
}
});
Html
<input type="hidden" id = "edit_id" value= "">
Jquery for finding the clicked
$('.editByAnchor').change(function() {
alert("You just clicked checkbox with the name " + this.id)
});
Produces the output
<a class="editByAnchor" id="1" href="#" data-toggle="modal" data-target="#edit_address"><i class="fa fa-edit"></i></a>
/*more like this but id will be change base on the dynamically fields*/
The above output anchor tag having id attribute it will assigned dynamically as you see my code so how will I get the id attribute of each icon by clicking them.
For dynamically created element use on(). Also you have to use click event instead of change:
$('.editByAnchor').on('click', function() {
alert("You just clicked checkbox with the name " + this.id)
});
By taking the reference of this link I post a answer for this everything is alright I have to change my code by following
$(".editByAnchor").click(function(){
var id = this.id;
alert(id)
});
I need to create some multiple input field dynamically on onkeypress event using JavaScript/jQuery.
I have one text-box,when user is entering any key on that text area two input field and second text-box is opening. When user will enter any key on second text box again another two input field and third text-box will open and so on. There is also a cross button is creating to close each individual set of text-box. In my current code I doing this putting all field static as user may create many numbers of input field so that I want to create those in dynamically with different name and id.
My code is in this Plunkr.
EDIT: Misunderstood question, answer below
This can easily be done if you have a specific field in which to create the input fields. For example, I will load input fields into document.body
Everytime you call newinput() an input field is created in parent who's id starts at input0 and increments each time
var id = 0;
var newinput = function() {
var parent = document.body
var field = document.createElement("input")
field.className = "myclassname"
field.style = "display:block;"
field.id = "input" + id;
parent.appendChild(field);
id += 1;
}
<body>
<div>Click plus to add input</div>
<button type="button" name="button" onclick="newinput()">+</button>
</body>
In your case, it looks like you want to add a group, you can do this:
var fieldgroup = document.querySelector(".questionshowp .form-group").cloneNode(true); // (1)
var addinput = function(){
var parent = this.parentNode.parentNode.parentNode; // (2)
var n = parent.querySelectorAll(".form-control").length
var f = fieldgroup.cloneNode(true);
f.children[0].id = "question"+n // (3)
f.querySelector(".secondsec").querySelector("button.btn-success").onclick = addinput // (4)
parent.insertBefore(f,parent.querySelector(".clear")); // (5)
}
Create a copy of a field-group to be used as a template
Get the container of input fields
Set the input field id with regard to total number of form-groups in parent
Make sure template applies addinput() to button
Insert input form before end of parent form
The easiest way apply this function to all + buttons is with JQuery
$("button.btn-sm.btn-success").on("click", addinput)
This would need to be located at the bottom of your html file, and below addinput() definition
EDIT: Real Answer
Turns out I wrote all that and just realized I misunderstood your question.
Still we can use the same principle to do what I believe you are asking
master = document.querySelector(".aquestionpart"); // (1)
form = document.querySelector(".questionparts"); // (2)
function show(){
var f = form.cloneNode(true);
var n = master.querySelectorAll(".questionparts").length;
f.id = "questionparts"+(n+1); // (3)
f.querySelector("#questions").onkeypress = show; // (4)
this.parentElement.parentElement.querySelector("#questionparts"+ n + " > .questionshowp").style ="display:block;"; // (5)
this.onkeypress = undefined; // (6)
master.insertBefore(f,master.children[master.children.length-1]) // (7)
}
form.querySelector("#questions").onkeypress = show; // (8)
form = form.cloneNode(true); // (9)
Get poll container
Get poll question form to use as template
Set new poll question form id with respect to number of others
Set show function to new poll question
Show multiple choice
Make sure subsequent keypresses dont create more questions
Insert question before .clear
sets up first question to show
creates copy of fresh question to use as template
With this your current scripts.js is unnecessary, and .aquestionpart must look like this for proper formatting
<div class="aquestionpart">
<div class="questionparts" id="questionparts1">...</div>
<div class="clear"></div>
</div>
From within .questionparts be sure to remove onkeypress="show();" from input. It should look like this.
<input name="questions" id="questions" class="form-control" placeholder="Questions" value="" type="text">
And finally an interesting note is that both of the scripts I've provided can be used together! (With some slight modifications)
//Author: Shane Mendez
var fieldgroup = document.querySelector(".questionshowp .form-group").cloneNode(true);
var addinput = function(){
var parent = this.parentNode.parentNode.parentNode;
var n = parent.querySelectorAll(".form-control").length
var f = fieldgroup.cloneNode(true);
f.children[0].id = "question"+n
f.querySelector(".secondsec").querySelector("button.btn-success").onclick = addinput
console.log(parent)
parent.insertBefore(f,parent.children[parent.children.length-1]);
}
master = document.querySelector(".aquestionpart");
form = document.querySelector(".questionparts");
function show(){
var f = form.cloneNode(true);
var n = master.querySelectorAll(".questionparts").length;
f.id = "questionparts"+(n+1);
f.querySelector("#questions").onkeypress = show;
console.log(this)
this.parentElement.parentElement.querySelector("#questionparts"+ n + " > .questionshowp").style ="display:block;";
this.onkeypress = undefined;
master.insertBefore(f,master.children[master.children.length-1])
$(f.querySelectorAll("button.btn-sm.btn-success")).on("click", addinput)
}
form.querySelector("#questions").onkeypress = show;
form = form.cloneNode(true);
$("button.btn-sm.btn-success").on("click", addinput)
If you put this in your scripts.js file and put that at the bottom of your body tag, then the only thing left is the - buttons.
You can use this Press to add multiple input field inside a div dynamically using jQuery. Here you only need to call the function that takes two parameter HTMLElement and config like:
$(".addInput").click(function() {
build_inputs($(this), config);
});
In the config you can add numbers of inputs form config like:
let config = {
title: "Slides",
forms: [
{
type: "text",
name: "name",
class: "form-control mb-2",
placeholder: "Enter Data..."
},
{
type: "file",
name: "image",
class: "btn btn-light btn-sm mb-2 btn-block"
},
{
type: "number",
name: "mobile",
class: "form-control mb-2",
placeholder: "Enter Data..."
}
],
exportTo:$('#getData')
};
I am trying to figure out how to clone this div so that the cloned version has product 2 as its class name as well as the input nams to have rate2 and notes2.
<div class="product1">
<input id="rate1" name="rate1" type="number">
<input name="notes" type="text">
<div>
Trying to append in here ****
<div class="sixteen columns" id="addproduct">
<label><i class="fa fa-plus-square"></i> Add another product</label>
</div>
=================================================================================
I have a rough idea of how to clone it but thats as far as my knowledge goes. I have looked at other posts and can't see an easy way of doing it.
JQuery-
$(document).ready(function(){
$("#addproduct").click(function(){
$(".product1").clone().appendTo("body");
});
});
Thanks for any help!
Why don't you try to keep a counter for sake of simplicity and increment it every time you add a new row (product). Something like this:
$(document).ready(function(){
// the counter:
var productID = 1;
// the click handler:
$("#addproduct").click(function() {
// clone last added product:
var nextProduct = $(".product" + productID).clone();
// add corresponding classes (remove old first):
nextProduct
.removeClass('product' + productID)
.addClass('product' + (++productID));
// update id and name to the first input:
nextProduct.find('input').eq(0).attr({
id: 'rate' + productID,
name: 'rate' + productID
});
// update name of the second input
nextProduct.find('input').eq(1).attr('name', 'notes' + productID);
// append to the body:
$('body').append(nextProduct);
});
});
This should do the job, although I'd recommend adding some identifiers to the two inputs (e.g. different class names, so you would avoid using the .eq() expression.
Live demo: http://jsbin.com/puluf/1/edit
Hope this helps!
Well I suggest you to use product-1 ,product-2 and so on as your ID and maybe product as your class name. By doing so, you can come up with something like this:
$("#addproduct").click(function(){
var temp = $(".product").last().prop('id').split("-");
$(".product").last().clone().appendTo("body");
var result = parseInt(temp[1]) + 1;
//assume this last product is the one that already added
$(".product").last().prop("id", "product-"+result);
});
Another way:
$("#addproduct").click(function(){
var temp = $(".product").last().prop('id').split("-");
var result = parseInt(temp[1]) + 1;
var html = $(".product:nth-child(1)").html();
$(".product").last().after('<div id="product-'+result+'" class="product">'+html+'</div>');
});
Edit, updated (v3)
Try
html (added 1 to end of attribute name , i.e., substitute notes1 for notes)
<input name="notes1" type="text" />
js (v3)
$(document).ready(function () {
$("#addproduct").on("click", function () {
var clone = $("[class^=product]:last")
.clone(false, false)[0].outerHTML.replace(/(\d)/g, function(a) {
return parseInt(a) + 1
});
$(clone).appendTo("body");
// console.log($(clone).attr("class"));
});
});
jsfiddle http://jsfiddle.net/guest271314/z2nxe84e/
var linksInCategory = document.id($('.CategoryTreeLabel').href);
var randomLinkArray = new Array(linksInCategory);
//CategoryTreeLabel is the class all the anchor tags have that contain the href with the link to the page I want
function goThere(link)
{
var the_url = function pickRandomURL () {
var random_url = randomLinkArray[Math.floor(Math.random()*randomLinkArray.length)];
the_url = random_url;
}
var good_url = fixURL(the_url);
var new_window = window.open(good_url,"new_window","menubar, resizeable. location, toolbar, status, scrollbars");
}
function fixURL(the_url) {
var the_first_seven = the_url.substring(0,7);
the_first_seven = the_first_seven.toLowerCase();
if (the_first_seven != 'http://')
{
the_url = "http://" + the_url;
}
return the_url;
}
</script>
</head>
<body>
<form name="the_form">
<input type="button" name="the_url" class="broadGroups" onClick="goThere(this)" src="the_url" value="Sports"></input>
<input type="button" name="the_url" class="broadGroups" onClick="goThere(this)" src="the_url" value="Film"></input>
Basically I want to create an array of all the href links within the same tag as the class="CategoryTreeLabel" Then I want to create a function goThere () that will open a new window with the URL of good_url. the_url needs to be randomly selected from the list of links we grabbed from the tags with a class of "CategoryTreeLabel" in the document.
Each of the buttons should call the goThere(this) function and pick a random URL out of the array we created, check if it has http:// (it always will redirect to a page without it, but i left it in for fun), then open that page
The return from the jQuery function is an array-like object, that is to say that it has a .length property and can be accessed with array-style [] bracket notation, so you don't really need to create a separate array variable too.
I notice that your buttons seem to be for different categories of links, like sports or film, so perhaps your intention is that the "Sports" button will select a random sports-related link while the "Film" button will select a random film-related link? If so you could have each button pass the category through to your goThere() function and select a random link from within that category. Something like this:
function goThere(category)
{
// assume that the parameter is the class name for links
// in the desired category
var $myLinks = $("a." + category);
// check if there are any matching links
if ($myLinks.length === 0) {
alert("Sorry, no links in the " + category + " category.");
return;
}
var url = fixURL($myLinks[ Math.floor(Math.random()*$myLinks.length) ].href);
var new_window = window.open(url,"new_window",
"menubar, resizeable. location, toolbar, status, scrollbars");
}
You'd then set up your anchor tags to have class names with appropriate categories, something like this:
<a class="sports" href="http://somesportssite.com">Super sports</a>
<a class="film" href="http://moviesRus.com">Movies</a>
<a class="film" href="http://animationplus.com">All about animation</a>
<a class="sports" href="http://football.com">Football site</a>
<a class="sports" href="http://skydiving.com">Let's jump!</a>
And the associated buttons would be:
<input type="button" value="Sports">
<input type="button" value="Film">
And you could set inline handlers like you had, onclick="sports", or you could do something like the following in your document.ready handler to set them all up with a single jQuery .click() call that assumes the appropriate classname/category is a lowercase version of the button label:
$('input[type="button"]').click(function() {
goThere(this.value.toLowerCase());
});