I have html being generated from Javascript to create a list of items. I also need to call a Jquery Ajax call on each of those items but since it isn't in the html from the page ready I think that might be why the Ajax isn't called. When I click the submit button it tries to refresh the page so this shows that the prevent default isn't being run.
EDIT: spelling
What am i doing wrong here?
Javascript that generates HTML:
buildCollectionList()
function buildCollectionList(){
var url = 'http://localhost:8000/api/collection_items_list/'
fetch(url)
.then((resp) => resp.json())
.then(function(data){
for (var x in data){
var wrapper = document.getElementById(`collection_scroll${data[x].post}`)
var product = wrapper.getAttribute('name')
//console.log(product)
wrapper.innerHTML = ''
/*fetch(url)
.then((resp) => resp.json())
.then(function(data){
console.log('Data:', data)*/
var list = data
for (var i in list){
if ((list[i].saved == true) && (list[i].post == product)){
var item = `
<div class="collection_save_container">
<div class="collection_save_name">${list[i].parent_collection_name}</div>
<form class="collection_save_form" action="" method="POST" id="${list[i].collection}" name="${list[i].post}">
<button type="submit" class="collection_save_btn saved" id="save_btn ${list[i].collection} ${list[i].post}"><div class="saved_text ${list[i].collection}">Saved</div></button>
</form>
</div>
</div>
`
wrapper.innerHTML += item
} else if (list[i].post == product){
var item = `
<div class="collection_save_container">
<div class="collection_save_name">${list[i].parent_collection_name}</div>
<form class="collection_save_form" action="" method="POST" id="${list[i].collection}" name="${list[i].post}">
<button type="submit" class="collection_save_btn" id="save_btn ${list[i].collection} ${list[i].post}"><div class="saved_text ${list[i].collection}">Save</div></button>
</form>
</div>
</div>
`
wrapper.innerHTML += item
}
}
//})
}
})
}
Jquery Ajax:
$(document).ready(function() {
$('.collection_save_form').submit(function(e){
e.preventDefault()
//const url = $(this).attr('action')
const url = "{% url 'savepost' 0 1000 %}"
const post_id = $(this).attr('name')
const collection_id = $(this).attr('id')
const text = $(`.saved_text ${collection_id}`).text()
var saveElement = document.getElementById(`save_btn ${collection_id} ${post_id}`);
real_url = url.replace('0', post_id).replace('1000', collection_id);
$.ajax({
type: 'POST',
url: real_url,
data: {
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
'post_id': post_id,
'collection_id': collection_id,
},
success: function(response){
if (saveElement.classList.contains("saved")){
saveElement.classList.remove("saved")
$(`.saved_text${collection_id}`).text('Save')
} else if (!saveElement.classList.contains("saved")) {
saveElement.classList.add("saved")
$(`.saved_text${collection_id}`).text('Saved')
}
console.log(post_id)
},
error: function(response){
console.log('error', response)
}
})
})
});
for anyone with a similar problem: i solved this by putting an onclick event in the html that is generated by javascript
Related
$('#addToCart').click(function () {
let csrf = $("input[name=csrfmiddlewaretoken]").val();
let trTable = $(this).parents('div')[1];
let customPrice = $($(trTable).children('div')[0]).find('#customPrice').val();
let quantity = $($(trTable).children('div')[1]).find('#quantity').val();
let productID = $('#addToCart').attr('data-product-id');
$.ajax({
url: "{% url 'cart:cart_add' %}",
method: 'POST',
dataType: 'json',
data: {
'csrfmiddlewaretoken': csrf,
productID: productID,
quantity: quantity,
customPrice: customPrice
},
success: function (data) {
$('#exampleModal').modal('hide');
let cart = $('#cart').children('tr');
let id = null;
jTotal = $('#total')
let trTable = $(this).parents('td');
let quantityField = '';
for (let i = 0; i < cart.length; i++) {
let tds = $(cart[i]).children('td')
let td = $(cart[i]).children('td')[tds.length - 1];
let ID = $(td).children('button').attr('data-product-id');
if (ID == data.id) {
quantityField = $(cart[i]).children('td')[1];
totalPriceField = $(cart[i]).children('td')[2];
id = ID;
}
}
if (data.id == id) {
$(quantityField).text(data.quantity);
$(totalPriceField).text(data.total);
jTotal.find('.total').find('.num').html(data.totalPrice);
} else {
$('#cart').append(
`<tr>
<td class="jsgrid-cell productName">${data.name}</td>
<td class="jsgrid-cell productQuantity" >${data.quantity}</td>
<td class="jsgrid-cell totalPrice">${data.total}</td>
<td class="productID"">
<button type="button" data-product-id="${data.id}" class="btn btn-sm btn-danger remove mgt"><i class="fa fa-trash"></i></button>
</td>
</tr>
`);
jTotal.find('.total').find('.num').html(data.totalPrice);
}
$('.remove').one("click", function() {
const result = confirm('Вы точно хотите удалить этот товар из корзины?');
if (result) {
let csrf = $("input[name=csrfmiddlewaretoken]").val();
let trTable = $(this).parents('td');
$.ajax({
url: "{% url "cart:cart_remove" %}",
method: 'POST',
dataType: 'json',
data: {
'csrfmiddlewaretoken': csrf,
productID: data.id,
},
success: function (data) {
sellPrice = $(trTable.parents('tr').find('.totalPrice')).html();
absoluteTotalPrice = jTotal.find('.total').find('.num').html();
totalCost = Number(absoluteTotalPrice) - Number(sellPrice);
jTotal.find('.total').find('.num').html(totalCost);
trTable.parents('tr').remove();
}
});
}
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Button .remove should work only once, how can i make this happen? It spawns multiple times. For example if click that addToCart button 2 times, this remove is spawning to times in a row, i need it so that it will just once.
My problem is that i have products and i add them via this button $('#addToCart').click(function () using ajax, and i have cart that is storing products. This button $('.remove').click(function () should be added to each product, but this button is in #addToCart button, and when multiple products is added, $('remove") button is working multiple times too.Sorry for bad english
You can simply use jQuery one to call your ajax request once per element.
Run snippet below to see it work only once.
$(".click-me").one("click", function() {
console.log("clicked");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="click-me">Remove</button>
You can use on and off to avoid a double click.
$(".remove").on("click", function() {
$(".remove").off("click");
console.log("clicked");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="remove">Remove</button>
You could use offto remove the event listener after your onclick event
$('.remove').click(
function () {$('.remove').off("click")
//...
I am trying to get my search box to work and do a getJSON on text search and title. but in the console log, I get text=undefined?title=undefined. so it is not displaying any JSON. Not sure if my click is working correctly or if I have to make my JSON objects?
Script
<script>
var searchstring = $('input[type="text"]', this).val();
var url = "https://data.edu/api/v1/metadata";
url += "?text=" + searchstring;
url += "?title=" + searchstring;
$(document).ready(function() {
$('button[type="button"]').click(function(event){
$.ajax({
type: "GET",
url: url,
success: function(res){
console.log(res);
var items = res.data.metadata;
var ins = "";
for (var i = 0; i < items.length; i++){
ins += "<div>";
ins += "Title" + items[i].title;
ins += "Title" + items[i].title;
ins += "Title" + items[i].title;
ins += "</div><br />";
};
$('#results').html(ins);
}
});
});
});
</script>
html
<form class="destinations-form" role="search" >
<div class="input-line">
<input id="searchForm" type="text" class="form-input check-value" placeholder="Search Documents" />
<button type="button" class="form-submit btn btn-special" "</button>
</div>
</form>
<div class="container">
<div class="hero-text align-center">
<div id="results"></div>
</div>
</div>
json
data: [
{
collection_id: "ADGM-1552427432270-483",
metadata:{
year: "2019",
files: text ,
title: text,
},
The problem is because you only read the values from the field when the page first loads and it is empty. To fix this, move that logic inside the click handler.
The next issue is that you should remove this from $('input[type="text"]', this). You don't need a contextual selector here, and this one is incorrect regardless.
Also note that a valid querystring starts with ? and separates each value with &, so your url concatenation needs to be amended slightly. In addition you shouldn't update the url value on every click. If you do it this way your AJAX request will only work once.
Lastly the metadata in your response is an object, not an array. data is the array so you need to loop over that instead. The loop can also be simplified by using map(). Try this:
$(document).ready(function() {
const url = "https://data.edu/api/v1/metadata";
$('button[type="button"]').on('click', function(e) {
let searchstring = $('input[type="text"]').val();
let requestUrl = url + `?text=${searchstring}&title=${searchstring}`;
$.ajax({
type: 'GET',
url: requestUrl,
success: function(res) {
let html = res.data.map(item => `<div>Title ${item.metadata.title}</div><br />`);
$('#results').html(html);
}
});
});
});
I have a form with text fields which the user can "Add New" by clicking a button. These fields share the same name. I'm trying pass the values into Google Spreadsheets, but the values all come through as 'undefined' with the following code, even though console.log prints the answers as strings which look okay to me.
So if the user for example submits 3 separate entries for SUNDAY_NOTES[], all 3 strings should end up in one cell broken up by new lines, but instead I'm just getting "undefined".
<form action="" method="post" id="timesheet">
<input type="text" name="SUNDAY_NOTES[]">
<input type="text" name="SUNDAY_NOTES[]">
<input type="text" name="SUNDAY_NOTES[]"> // the user can create multiples of these ^ for each day of the week
<input type="submit" id="submit" />
</form>
<script>
$(document).ready(function() {
var $form = $('form#timesheet'),
url = 'https://script.google.com/macros/s/AKf45XRaA/exec'
$('#submit').on('click', function(e) {
e.preventDefault();
var jqxhr = $.ajax({
url: url,
method: "GET",
dataType: "json",
data: $form.serializeArray().map((e) => {
return e.value
}).join('\n')
});
})
});
</script>
Your code works. In the snippet below I am storing the data split by \n in a variable and logging it. You can check the output.
Although your JS is correct, I suspect that you actually want to be using a different HTTP method. Perhaps POST or PUT? I can't be specific as you have not said which API endpoint you are using.
$(document).ready(function() {
var $form = $('form#timesheet'),
url = 'https://script.google.com/macros/s/AKf45XRaA/exec'
$('#submit').on('click', function(e) {
e.preventDefault();
var data = $form.serializeArray().map((e) => {
return e.value
}).join('\n');
console.log(data);
var jqxhr = $.ajax({
url: url,
method: "POST",
dataType: "json",
data: data
}).done(response => {
console.log(response);
}).fail((jqXHR, textStatus) => {
console.log("Request failed: " + textStatus);
});
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="" method="post" id="timesheet">
<input type="text" name="SUNDAY_NOTES[]">
<input type="text" name="SUNDAY_NOTES[]">
<input type="text" name="SUNDAY_NOTES[]">
<input type="submit" id="submit" />
</form>
remove the [] from your input's name as this is needed if you want to receive an array in the server side, then create a function that groups the values according to the inouts' keys :
function group(arr) {
var tempArr = [];
arr.forEach(function(e) {
var tempObj = tempArr.find(function(a) { return a.name == e.name });
if (!tempObj)
tempArr.push(e)
else
tempArr[tempArr.indexOf(tempObj)].value += ', ' + e.value;
});
return tempArr;
}
and use it like :
$('#submit').on('click', function(e) {
e.preventDefault();
var jqxhr = $.ajax({
url: url,
method: "GET",
dataType: "json",
data: group($form.serializeArray()),
//... rest of your code
this will keep the original structure that works,
here's a snippet :
var $form = $('form#timesheet');
function group(arr) {
var tempArr = [];
arr.forEach(function(e) {
var tempObj = tempArr.find(function(a) { return a.name == e.name });
if (!tempObj)
tempArr.push(e)
else
tempArr[tempArr.indexOf(tempObj)].value += ', ' + e.value;
});
return tempArr;
}
$form.submit(function(e) {
e.preventDefault();
var grouped = group($form.serializeArray());
console.log(JSON.stringify(grouped))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post" id="timesheet">
<input type="text" name="SUNDAY_NOTES"><br />
<input type="text" name="SUNDAY_NOTES"> // user can click a button to keep adding more SUNDAY_NOTES fields
<input type="text" name="MONDAY_NOTES"> // and so forth
<input type="submit" id="submit" />
</form>
When a user searches for a username he gets results. When he backspaces or modifies the query, the results just keep getting added on top of the previous results instead of the results being modified and a fresh, updated result returned. I have modified the script here and there with no success yet.
My view:
<div class='container'>
<div class='row'>
<div class='col-sm-6 col-xs-12 col-centered'>
<div class='panel panel-default'>
<div class='panel-heading sticky'>
<div class='back pull-left'><a href='<?php echo site_url('chats') ?>'><span class='glyphicon glyphicon-chevron-left'></span></a></div>
<h1 class='panel-title text-center'>New Chat</h1>
<input class='form-control' id='search-field' type='text' placeholder='Username'>
</div>
<div class='panel-body'>
<ul class='users collapse'>
</ul>
</div>
</div>
</div><!--end column-->
</div><!--end row 1-->
</div><!--end container-->
My JS:
$(function() {
var $search_field = $('#search-field');
$search_field.on('keyup', searchByUsername);
$search_field.focus();
});
function searchByUsername(e) {
var username = this.value.trim();
var keyCode = e.keyCode;
var data = {username : username};
var $usersElement = $('.users');
var users = [];
// Use this condition to prevent searching when whitespace is entered
if (username) {
var request = $.ajax({
url : site_url + 'search/searchByUsername/',
method : 'GET',
data : data,
dataType : 'json'
});
request.done(function(jsonRepsonse) {
if (jsonRepsonse) {
var status = jsonRepsonse.status;
var usernames = jsonRepsonse.usernames;
if (status === 'success') {
$.each(usernames, function(index, value) {
// must be one line or will throw syntax error
users.push("<li class='user text-center'><a href='#'><span class='glyphicon glyphicon-user'></span><strong class='username'>" + value + "</strong></a></li>");
});console.log(users);
$usersElement
.append(users)
.show();
}
}
});
request.fail(function(xhr, status, error) {
console.log(error);
});
}
users.length = 0
$usersElement.hide();
}
My Codeigniter controller function:
public function searchByUsername()
{
$username = $this->input->get('username', true);
$usernames = [];
if (!empty($username)) {
$usernames = $this->find_users_model
->searchByUsername($username);
}
if (!empty($usernames)) {
$this->jsonResponse(
['status' => 'success',
'usernames' => $usernames]);
return;
}
$this->jsonResponse(
['status' => 'success',
'usernames' => ['User not found']]);
}
private function jsonResponse($response)
{
$this->output
->set_status_header(200)
->set_content_type('application/json', 'utf-8')
->set_output(json_encode($response));
}
Result:
This is your users container:
var $usersElement = $('.users');
On ajax response, you do:
$usersElement.append(users).show();
But you're always appending, never removing. Try emptying the element before populating it with users again:
$usersElement.empty().append(users).show();
i have form that need the previous value inserted....i'm using ajax,but the success: function(data) wont let me moved to the next page...
here is my code
HTML
<form>
<input type="text" name="id_1" id="id_1>
<input type="text" name="id_2" id="id_2>
<input type="text" name="id_3" id="id_3>
<button type="button" onclick="next();">
</form>
<div id="tabelna"></div>
JQuery
var id_1 = $('#id_1').val();
var id_2= $('#id_2').val();
var id_3= $('#id_3').val();
var datana = 'id_1='+id_1+'&id_2='+id_2+'&id_3='+id_3;
var urlna="<?=base_url()?>something/something/something";
$.ajax({
type: 'POST',
url: urlna,
data: datana,
beforeSend:function(data){
},
message:"<center>><h3>Loading Data. . .</h3></center>"
});
},
error: function(data) {
jAlert('Failed');
},
success: function(data) {
load();
}
})
return false;
}
function load()
{
$('#tabelna').load('<?=base_url()?>something/something/something') (This is my mistake)
}
CONTROLLER
function set_value()
{
extract($_POST);
$d['id1'] = $this-db->query('SELECT * FROM TBL1 where id='.$id_1);
$d['id2'] = $this-db->query('SELECT * FROM TBL2 where id='.$id_2);
$d['id3'] = $this-db->query('SELECT * FROM TBL3 where id='.$id_3);
$this->load->view('something/v_add',$d); (this is my mistake)
}
How can i pass the submitted value to the controller and shows new form ?
we can call controller function using window.location
function load()
{
window.location.href = "<?php echo site_url('controller_d/login/admin_link_delete_user');?>";
}