Ajax call to get list of objects clicked on - javascript

I am trying to use an AJAX call to send data to my django view, which I then hope to use in another view. When a user clicks on a particular word, known_words must go up by one (this part works). But I also want to know which word the user clicked on (I have access to this in the template: {{item.0}}. And this is the part that I cannot get to work.
The relevant part of my html (this is the last column of my table, the first column contains {{item.0}}):
Yes
My js:
$(document).ready(function() {
var known_words = 0;
var clicked_words = [];
$(".word_known").click(function() {
known_words++;
var reference = this;
var songpk = $(this).data('songpk');
var userpk = $(this).data('userpk');
var clicked_words = $(this).data('clicked_words'); //I know this part is wrong, how can I append the word to the list?
$.ajax({
url: "/videos/songs/vocab/known/"+songpk+"/"+userpk+"/",
data: {known_words: known_words, clicked_words: clicked_words},
success: function(result) {
$(reference).removeClass("btn-warning");
$(reference).addClass("btn-success");
$(reference).text("Known");
},
failure: function(data) {
alert("There is an error!")
}
})
});
})
Views:
def word_known(request, pk_song, pk_user):
if request.method =='POST':
pass
elif request.method == 'GET':
known_words = request.GET.get('known_words', '')
clicked_words = request.GET.get('clicked_words', '')
request.session['known_words'] = known_words
clicked_words = []
clicked_words.append(request.session['clicked_words'])
print('The number of known words is {} and clicked words are {}'.format(known_words, clicked_words))
return HttpResponse(json.dumps(known_words))
In the console, when I click on a word (not 'hello'), I get the following in the console:
The number of known words is 1 and clicked words are ['hello']
And if I click a second time on a different word:
The number of known words is 2 and clicked words are ['hello']
So the counter is working, but not the word list. How can I fix that?

I haven’t tested this, but I think you are overwriting the Array instead of adding to it.
This line
var clicked_words = $(this).data('clicked_words');
Should be
clicked_words.push($(this).data('clicked_words'));
This is a link to the documentation on MDN

In addition to #Daniel Butler's answer, I had to change my view as follows:
clicked_words = request.GET.getlist('clicked_words[]')
Because apparrently when you send a list through jQuery it changes the keyword as well.

Related

Making a counter for #StopTheFire

So, I just wanted to make a counter for #StopTheFire Which how can I extract the number from <span>? I also saw some post on twitter asking about this. With JavaScript. Can I use WrapAPI for this? Thanks.
Part of the code from StopTheFire.gg:
<span>$25,692</span>
Get the html of the site
Use jQuery:
$.ajax({ url: 'your-url', success: function(data) { alert(data); } });
This data is your HTML.
.getElementsByTagName("span") will return you a collection of elements. Here you might have to parse first and select by id or class because there will be wrong spans...
Then, you might want to use .innerHTML:
For your case you would just loop through
var spans = document.getElementsByTagName("span");
and for each of those
var array_values = []
var value;
for(key in spans) {
value = spans[key].innerHTML;
array_values.push(value)
}

How do I get the specific part of a URL using jQuery and JavaScript?

I am checking out an order in WordPress via jQuery AJAX. Upon successfully posting, WordPress returns a response to me with a result success value and url value.
I want to get the particular part of this url so I can use the id as an object for my purpose.
This is the structure of the url: http://localhost/mywebsite/checkout/order-received/28564?key=wc_order_5b4dbc6b2f459
This is my current code:
j('.my-checkout').on('submit', function(evt) {
evt.preventDefault();
var billing_customer_type = j("#billing_customer_type").val();
// and so on...
j.ajax({
type: 'POST',
url: 'http://localhost/mywebsite/ajax=checkout',
cache: false,
data: {
'billing_customer_type': billing_customer_type,
// and so on..
},
success: function(result) {
var orderResponseUrl = result.redirect;
j('.order-response-url').html(orderResponseUrl);
// http://localhost/mywebsite/checkout/order-received/28564?key=wc_order_5b4dbc6b2f459
orderResponseUrl.split("/");
console.log(orderResponseUrl[3]);
},
error: function(xhr, status, error) {
console.log(error);
},
complete: function() {}
});
});
The result of my code above is just the the letter "p". I think because it started of the first letter of http and I used the index [3].
Do you know how can I get the specific part of the url that is 28564?
If the URL that you need to interact with is always the same, you can split the returned url at the 'order-received/' portion (which gives an array of everything before that, and everything after it).
Then rather than splitting again on the '?" which is another way of doing it - you can use parseFloat() to get the order number. This works since parseFloat returns all numerical values up to but not including the first non-numerical character ("?").
var urlStr = 'http://localhost/mywebsite/checkout/order-received/28564?key=wc_order_5b4dbc6b2f459';
var orderNumber = parseFloat(urlStr.split('order-received/')[1]);
console.log(orderNumber); //gives 28564
Because when you do orderResponseUrl.split("/"); it does NOT change orderResponseUrl, it creates a new array.
var parts = orderResponseUrl.split("/");
console.log(parts);
if the length is always same then you can use substring function.
var str = "Hello world!";
var res = str.substring(1, 4);
now res contain
console.log(res); // ell
if you do not know the index, you can find like this.
var str = "Hello world, welcome to the universe.";
var n = str.indexOf("welcome");
now n look like
console.log(n); // 13

Display the results of an array on another page

I'm trying to load an array from one page and then have the results appear on another using javascript/jQuery. So a user will make a selection from a dropdown. Based on this dropdown the "customers" address, phone, email, etc. will appear in a text field. I'm trying to store those results in to the array (name | address | etc in one index of the array), display the result on the second screen, and then allow the user to add more names if necessary.
At the moment I'm trying to use localStorage to store the values and then JSON.stringify to convert the results so they can be stored in the array.
I think these are all of the pertinent lines:
var customerArray = [];
var getName = $('#DropDownList1').val();
var getAddress = $('#DataList1').text().trim();
var getPhone = $('#DataList2').text().trim();
var getEmail = $('#DataList3').text().trim();
//store the variables
localStorage.setItem("name", getName);
localStorage.setItem("address", getAddress);
localStorage.setItem("phone", getPhone);
localStorage.setItem("email", getEmail);
//user will click #btnAdd to add the customers information
//into customerArray[]
$("#btnAdd").click(function () {
var setName = localStorage.getItem("name");
var setAddress = localStorage.getItem("address");
var setPhone = localStorage.getItem("phone");
var setEmail = localStorage.getItem("email");
var post = setName + setAddress + setPhone + setEmail;
if (customerArray.length == 0) {
customerArray[0] = post;
} else {
for (var i = 1; i < customerArray.length; ++i) {
//store results of 'post' into the array
customerArray.push(post);
localStorage.setItem("storedArray",JSON.stringify(customerArray));
}
}
}); //end #btnAdd click event
Form here the 2nd page will load with a text field that will (should) display the results of the array (customerArray). Unfortunately I can only get 1 value to appear.
At the moment this is the block being used to display the results:
$('#tbContactList').val(JSON.parse(localStorage.getItem("storedArray")));
If it matters I'm writing the application using Visual Studio Express 2012 for Web. The data that initially populates the customers information comes from a database that I've used ASP controls to get. I'm confident there is a perfectly simple solution using ASP/C# but I'm trying to solve this problem using javascript/jQuery - I'm more familiar with those languages than I am with C#.
Thank you.
Use Array.join() to turn your array into a string to store.
Then use Array.split() to turn your string back into an Array.
Example
var arr=['name','email','other'];
var localStorageString=arr.join(',');
localStorage.setItem('info',localStorageString);
var reassemble=localStorage.info.split(',');
for(var i=0;i<reassemble.length;i++){
document.body.innerHTML+=reassemble[i]+"<br/>";
}
http://jsfiddle.net/s5onLxd3/
Why does the user have to leave the current page though? IS a tabbed/dynamic interface not an option?

JavaScript Asp.net repeating controls

I am trying to do the folowing with Asp.net 3.5/IIS
A web form with a top level repeatable form. So basically a Order->Products->ProductsParts kinda of scenerio. Order is only one. Product is repeatable. Each product has repeatable products parts. The product and product part have a whole bunch of fields so I cannot use a grid.
So, I have add/remove buttons for Product and within each product add/remove buttons for each product part.
That is my requirement. I have been able to achieve add/remove after some research using jquery/js. How, do i capture this data on the server? Since javascript is adding and removing these controls they are not server side and I don't know how to assign name attributes correctly. I am trying following javascript but it ain't working:
function onAddProperty(btnObject){
var previous = btnObject.prev('div');
var propertyCount = jquery.data(document.body, 'propertyCount');
var newDiv = previous.clone(true).find("*[name]").andSelf().each(function () { $(this).attr("name").replace(($(this).attr("name").match(/\[[0-9]+\]/), cntr)); }); ;
propertyCount++;
jquery.data(document.body, 'propertyCount', propertyCount);
//keep only one unit and remove rest
var children = newDiv.find('#pnlUnits > #pnlUnitRepeater');
var unitCount = children.length;
var first = children.first();
for (i = 1; i < unitCount; i++) {
children[i].remove();
}
newDiv.id = "pnlPropertySlider_" + propertyCount;
newDiv.insertBefore(btnObject);
}
I need to assign name property as array so that I can read it in Request.Form
Fix for not updating ids not working:
var newDiv = previous.clone(true).find("input,select").each(function () {
$(this).attr({
'name': function () {
var name = $(this).attr('name');
if (!name) return '';
return name.replace(/property\[[0-9]+\]/, 'property' + propertyCount);
}
});
}).end().insertBefore(btnObject);
The issue looks like the following line:
$(this).attr("name").replace(($(this).attr("name").match(/\[[0-9]+\]/), cntr));
This statement doesn't do anything. Strings in JavaScript an immutable, and .replace only returns the string with something replaced.
You would then have to actually set the attr("name") to the new string that has the replaced value:
http://api.jquery.com/attr/
I can't help much more without seeing your HTML.

More user friendly search box in MVC

I have implemented searchbox using jQuery. Here is the code which sends search term and
after that I receive Json which I use to make list of matched searched items.
The problem is that on each keyup I delete all matched items :
$("#realPlaceForSearchItems").html("");
because if I don't that I get duplications when searching for product if I enter "pro" and then type "d". (I am appending list items to the list) Is it possible to achieve that I somehow just delete elements that do not match "prod" (which previously matched "pro" ofcourse) and that elements that match prod stay untouched after typing "d".
$("#searchInput").keyup(function () {
$this = $(this);
$('#realPlaceForSearchItems').show();
$("#realPlaceForSearchItems").html("");
var seachedTerm=$this.val();
if ($this.val().length> 2)
{
$("#realPlaceForSearchItems").html("");
$('#realPlaceForSearchItems').show();
$.ajax({
type: "POST",
url: ROOT + "Filter/Search/",
data: {term: $this.val()},
success: function (data)
{
var Link = $("#searchTemplate>li>a");
var placeForProductId=$("#searchTemplate>li>a>input");
var placeForPicture = $("#searchTemplate>li>a>div>img");
var placeForProductName = $("#searchTemplate>li>a>div>div");
var placeForPrice= $("#searchTemplate>li>a>div>span");
$.each(data.productsWereSeached, function () {
console.log("sddsd", data.totalrows);
var imagesFolder="/Content/images/";
var pathToProduct="/ProductDetails/Index/"
var slash = "/";
Link.attr("href", pathToProduct + this.Id);
placeForProductId.val(this.Id);
if (this && this.Picture) //for the case there is no any picture there would be error cant read propery or undefined
placeForPicture.attr("src", imagesFolder + this.Id + slash + this.Picture.FileName);
else
placeForPicture.attr("src", "");
placeForProductName.html(this.Name);
placeForPrice.html((parseFloat(this.Price) / 100.0).toString() + " kn");
$listItem = $("#searchTemplate").html();
$("#realPlaceForSearchItems").append($listItem);
});
$("#nOfMatchedProducts").val(data.totalrows);
if (data.totalrows > 2)
{
var searchurl="/Search/ShowMoreSearched?term="
$showMoreItem = $("#showMoreItem").html();
$("#showMoreItem>li>a").attr("href",searchurl+seachedTerm);
$("#realPlaceForSearchItems").append($showMoreItem);
}
},
failure: function ()
{
}
});
}
});
$.each(data.productsWereSeached, function () {
if($('a[href="'+pathToProduct + this.Id+'"]').length == 0) {
console.log("sddsd", data.totalrows);
var imagesFolder="/Content/images/";
var pathToProduct="/ProductDetails/Index/"
var slash = "/";
Link.attr("href", pathToProduct + this.Id);
placeForProductId.val(this.Id);
if (this && this.Picture) //for the case there is no any picture there would be error cant read propery or undefined
placeForPicture.attr("src", imagesFolder + this.Id + slash + this.Picture.FileName);
else
placeForPicture.attr("src", "");
placeForProductName.html(this.Name);
placeForPrice.html((parseFloat(this.Price) / 100.0).toString() + " kn");
$listItem = $("#searchTemplate").html();
$("#realPlaceForSearchItems").append($listItem);
}
});
Psst... I'm assuming you also want to limit calls to the server and that your search result list is not wildly huge!
So! Benefit to your current approach is you don't have to manage/compare any existing data set. This makes things easier when a search for "pro" changes to a search for "cro" or any other change that makes the previous AJAX call irrelevant. But, like you said, it leaves you with this clear then re-add items inefficiency when you search for "prod" after "pro".
Idea:
Store the most recent AJAX call criteria in a global.
If new search value includes the latest AJAX search value, filter/hide items in the existing data set which do not match the new criteria. Do not perform a new search.
If new value does not include the latest AJAX search value: clear current data set, update AJAX search value, execute new AJAX call
Pass the index from $.each (http://api.jquery.com/jQuery.each/) into your function, then use it to select the search result you will replaceWith (http://api.jquery.com/replaceWith/) the element you just built. In using this method, your four LI elements within the search results UL must exist before a search.keyup is executed.
Do this by changing two lines...
$.each(data.productsWereSeached, function (index) {
... all of the existing code in the loop stays the same except ...
$("#realPlaceForSearchItems LI:eq(" + index + ")").replaceWith($listItem);
});

Categories

Resources