I have (part of) a form HTML produced by a PHP loop:
<input type="text" class="store">
<input type="text" class="store">
<input type="text" class="store">
<input type="text" class="store">
The input goes in a db tables:
store
-------
cityID
cityname
store
I have a JavaScript that alerts me if the store entered is already in other cities:
$(document).ready(function() {
$('.store').on('change', function() {
var storeValue = $('.store').val();
$.post('stores.php', {'word': storeValue}, function(data) {
var verifStore = '';
var json = $.parseJSON(data);
$.each(json, function(k, v) {
verifStore += '[' + v.cityID + '] ' + v.cityName + '\n';
});
alert('Already in the following cities: ' + '\n' + verifStore);
});
});
});
Problem is that JavaScript is fired by the .class and I have more .class inputs in my form, so (of course) it doesn't work properly. How should I modify my JavaScript code? Maybe there is in JavaScript a way to consider each .class field separately... Something like .each or .foreach ...?
Let's say, you have been asked to put 4 different values for the city and they are not supposed to be present in the DB. I would create a class named error:
.error {border: 1px solid #f00; background: #f99;}
And now, I would go through each of the input using $.each:
$(".store").each(function () {
$this = $(this);
$this.removeClass("error");
$.post('stores.php', {'word': $this.val()}, function (data) {
if ( /* Your condition if the word is present. */ )
alert("Already there!");
});
});
Note that this code will send as many as requests to the server as many inputs are there. So handle with care.
You can optimize your function if you do just one request.
var values = $(".store").map(function(){
return this.value;
}); // values is an array
$this.removeClass("error");
// stores.php should be ready to receive an array of values
$.post('stores.php', {'word': JSON.stringify(values)}, function (data) {
var verifStore = '';
var json = $.parseJSON(data);
$.each(json, function(k, v){
verifStore += '[' + v.cityID + '] ' + v.cityName + '\n';
});
if(varifStore)
alert('Already in the following cities: ' + '\n' + verifStore);
});
SOLUTION (at least for me...)
After reading all answers and suggestions, I was able to make it work with this code. Hope it will be helpful for others :)
$(document).ready(function() {
$('.store').each (function(){//do it for every class .store
var $this = $(this); //get this object
$this.on('change', function(){ //when this change...
var searchValue = this.value; //assign the input to a variable
if (searchValue != ''){ //if the variable is not emprty
$.post('stores.php',{'term' : searchValue}, function(data) { //check and return data in alert
if (data.length < 10){ // if number not in db, green
$this.css({'border' : 'solid 4px #17BC17'});
}
var resultAlert = '';
var jsonData = $.parseJSON(data);
$.each(jsonData, function(k, v){
resultAlert += '[' + v.cityID + '] ' + v.cityname + ' ' + v.value + '\n';
}); //each
alert('ALERT!' + '\n' + 'store in other cities' + '\n' + searchValue + ': ' + '\n' + resultAlert );
$this.css({'border' : 'solid 4px #FFCC11'}); // if in db, yellow
});// post
}//close if
if (searchValue == ''){ //if the variable is empty, this turn green, if you delete a yellow number
$this.css({'border' : ''});
}
}); //close on change
});//close .each
});
Related
I have this code
$.getJSON( "https://domain.ltd/parse_data.php", function( data_recieved ) {
if (data_recieved.length) {
$.each(data_recieved, function(index, element) {
$( ".items" ).append( '<span>' + element.name + ' = ' + element.amount + '</span><br />' );
});
}
})
As you can see, it's parsing json and displaying results with append.
However, if there are 500 rows of data in the response, it can take up to 30 seconds to append all 500 lines. And while it's happening, the website is unresponsive.
Not only that, my CPU usage goes to 50%.
Am I doing it wrong? Maybe there is a more efficient way to parse through this much data and display it dynamicaly with jQuery?
I believe this to be a better solution
$.getJSON( "https://domain.ltd/parse_data.php", function( data_recieved ) {
if (data_recieved.length) {
var spns = '';
$.each(data_recieved, function(index, element) {
spns+='<span>' + element.name + ' = ' + element.amount + '</span><br />';
});
$( ".items" ).append(spns); // or use .html();
}
})
It seems like your DOM tree is deep & $( ".items" ) inside the loop is getting expensive.
You could improve your code so that the performance is better. At the bottom of the code I have applied and described a few tips. You can see the used time in the developer console of this page.
// just for simulating your JSON
var dataRecieved = [];
for (var i = 0; i < 500; i++) {
dataRecieved.push({ name: 'Element ' + i, amount: parseInt(Math.random() * i) });
}
// $.getJSON( "https://domain.ltd/parse_data.php", function( data_recieved ) {
// optimization start here
console.time('test');
// use a simple for loop and save the length of received data
var element, dataReceivedLength = dataRecieved.length;
// create a variable and append all html to it
var dataMarkup = '';
// if you want to do it on only one element, use the id as selector.
// save the object to a variable
var $items = $('#first-collection');
// check if $items exist
if ($items.length && dataReceivedLength) {
for (var i = 0; i < dataReceivedLength; i++) {
element = dataRecieved[i];
dataMarkup += '<span>' + element.name + ' = ' + element.amount + '</span><br />';
}
// use html() instead of append() for performance reasons in this case
$items.html(dataMarkup);
}
console.timeLog('test');
// });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="first-collection" class="items"></p>
How could I do a search by name and surname with an array javascript?
and every time I search something that begins with je, div=result show me all Name and Surnames with Je in this case Jessica and Jey;
this would be a onkeydown event, right?
<input type='text' id='filter' placeholder='search in array'>
here I print the result:
<div id='result'></div>
this is my array :
var datos = [ ['Jessica','Lyn',3],
['Jhon','Cin',5],
['Alison','Peage',1],
['Thor','zhov',12],
['Jey','hov',32]
];
$("#filter").on('keyup', function () {
var val = $(this).val();
$("#result").empty();
$.each(datos, function () {
if (this[0].indexOf(val) >= 0 || this[1].indexOf(val) >= 0) {
$("#result").append("<div>" + this[0] + ' ' + this[1] + "</div>");
}
});
});
http://jsfiddle.net/MqTBm/
var $result = $('#result');
$('#filter').on('keyup', function () {
var $fragment = $('<div />');
var val = this.value.toLowerCase();
$.each(datos, function (i, item) {console.log( item[0].toLowerCase().indexOf(val) );
if ( item[0].toLowerCase().indexOf(val) == 0 ) {
$fragment.append('<p>' + item[0] + ' ' + item[1] + '</p>');
}
});
$result.html( $fragment.children() );
});
Here's the fiddle: http://jsfiddle.net/GkWGk/
The simple answer is to run a for loop over the array checking each element. However this is not a good idea if you have a large array. There are many ways to index an array. Thinking off the top of my head I might build a second array that stores the fields joined as one string as the index and then the array reference. So you can for loop through the reference object. Find the entry with string comparisons. Take the index reference to the real array.
I have json with array of objects in it. I build my page depends on elements in this array. If there is no duplicate values of key called points, i render page with some info and description, using value of points to find this element in array. However if i have 2 and more duplicate values of key called points i render list of these elements. In this case i cant use value of points to find element in array. I know i can use index number of array element, and then pass it as parameter to my function that find and build info and description, but i'm not sure how to do that. How do i get index number of element in array?
P.S. Can provide my code if needed
Code that i'm using
var allRewards = null;
$("#reward").live('pagecreate', function(e) {
var request = $.ajax({
type: "GET",
url: "example.com/test.json"
dataType: "json",
error: function (data, textStatus){
console.log( "it`s error" );
console.log( status );
console.log( data );},
success: function (data, textStatus){
console.log( "success" );
console.log( status );
console.log( data );
}
})
request.success(function(data, textStatus){
var lis = "";
var arr = [];
var iter = 0;
allRewards = data
$.each(data.rewards, function(key, val){
if ($.inArray(val.points, arr) == -1)
{
lis += "<div data-points='"+ val.points +"'align=CENTER class = 'rewards-block ui-block-" + String.fromCharCode(97 + iter%3) + "'><a href ='#' class ='ui-link-inherit' onclick='showreward("+val.points+")'><img src ='./img/reward-icon.png'/><span>" + val.points + " pts</span></a></div>";
arr.push(val.points);
iter += 1;
}
});
$("#rewards_table").html(lis);
})
});
function showreward(point)
{
$.mobile.changePage('show-rewards.html')
console.log(allRewards);
$("#showrewards").live('pagecreate', function(e) {
var items = "";
var arr = [];
var counter = 0;
var result = $.grep(allRewards.rewards, function(e){ return e.points == point; });
if (result.length > 1)
{
$.each(result, function(key, val){
items += "<div style='color:white;'>" + val.title + "</div>"
console.log(val.title);
})
}
else if (result.length == 1)
{
// $.each(result, function(key, val){
// items += "div style='color:white;'"+ val.points + "></div>"
// console.log(val.points);
// })
$.each(result, function(key, val){
items += "<div style='background:white; padding:5px 5px 20px 5px;'><img style ='float:right; width:45%; margin-top:22px; padding: 0 0 10px 10px;' src ='" + val.main_photo_url + "'/><h3>"+ val.title + "</h3><p>" + val.description + "</p><p style='font-weight:bold; font-size:13px;'>Reedem below for " + val.points + " Zingle Points</p><table class='pagemenu' style='width:200px;'><tr><td class='width_5'><input type='submit' data-theme='w' value='Reedem Now' data-inline='true'></td><td><a data-role='button' data-icon='pagemenu-share' data-iconpos='notext' href='index.html' data-shadow='false' data-corners='false'></a></td></tr></table></div>"
});
}
console.log(items);
$("#rewards-list").html(items);
});
}
I think you're looking for Array.indexOf.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
PS. This is available in Underscore as _.indexOf.
Hey there,
Again, I've been searching a solution to find out why a function, would not being called... and guess what, I did not find.
I have a form, that I submit using jQuery Ajax. When error, I get every local data, I got, I sorted them, and show them to the user.
Here is the sample code :
$.ajax({
type: "POST",
url: "http://xxx/register.php",
data: form,
success: function(msg){
//console.log("Data Saved: " + msg);
$.iGrowl(2,stringdata[4]);
var data = parseJSON(msg);
if(data.msg.score != undefined){
var cpt = 0;
$.each(data.msg.score, function(index,el){
if(cpt<8){
if(el.selected)
$('tbody').append('<tr class="win"><td>' + el.name + '</td><td>' + el.score + '</td></tr>');
else
$('tbody').append('<tr><td>' + el.name + '</td><td>' + el.score + '</td></tr>');
}
});
}
else{
$.iGrowl(3,"Erreur inconnue...");
}
$("#scorediv").css("visibility","visible");
$( "#formule" ).css('opacity',0);
$( "#scorediv" ).css('opacity',1);
},
error: function(data) {
cpt = 0;
var i = 0;
score.each(function(r){
arrayScore[i] = r;
i++;
});
arrayScore.sort(function(a, b){
console.log("sorting...");
if(a[3])
{
if(b[3])
{
return (b[3].value - a[3].value); //causes an array to be sorted numerically and descending
}
}
});
$.each(arrayScore, function(index,el){
//arrayScore.forEach(function(el) {
//score.each(function(el){
if(cpt<8)
{
if(el[2].value == form[2].value)
$('tbody').append('<tr class="win"><td>' + el[1].value + '</td><td>' + el[3].value + '</td></tr>');
else
$('tbody').append('<tr><td>' + el[1].value + '</td><td>' + el[3].value + '</td></tr>');
cpt++;
}
else
return false;
});
var user = form;
store.save(user, function(r) {
});
$.iGrowl(3,stringdata[5]);
$("#scorediv").css("visibility","visible");
$("#formule").css('opacity',0);
$( "#scorediv" ).css('opacity',1);
}
});
My array is never sorted. If I change this part :
var i = 0;
score.each(function(r){
arrayScore[i] = r;
i++;
});
by this :
score.each(function(r){
arrayScore.push(r);
});
arrayScore is never filled.
I try to execute each line in the console step by step, it works.... I'm getting kind of crazy... and I really do not know what could have happened ?
Any help would be graceful appreciate !
P.S : I'm using, jQuery1.5 + Lawnchair and CSS3 animation.
Code tested on safari and chrome.
Thanks !
Javascript array objects don't support a method called each. You should try
$.each(score, function(index, value){...});
I have inherited a website! which was designed to work in IE and only IE it seems.. I've now been asked to make the site run in Firefox. I've fixed most of the bugs without any problems but this one has me stumped.
setTimeout(fDelayedFunc, 1000);
This line of Javascript, works fine in IE but in Firefox the function fDelayedFunc never fires. I've removed the setTimeout and the function wrapper and tried running the code as part of the main function. This works without any problems at all.
There is alot of code involved but here's the main but I'm having trouble with. If you'd like to see anymore of the code please let me know.
setTimeout(fDelayedFunc, 0);
//Save the current text box value
var vCurrentTBValue = vJQElement.val();
function fDelayedFunc() {
if (vJQElement.val() == vCurrentTBValue) {
alert("test");
//Get position list box should appear in
var vTop = vJQElement.position().top + 25;
var vLeft = vJQElement.position().left;
//Had to put a special case in for account due to the position co-ords being wrong. This is due to a css error
if (vHiddenFieldToWriteTo == "#ctl00_ContentPlaceHolder1_hfAccountCode") {
vTop = vJQElement.position().top + 58;
vLeft = vJQElement.position().left + 200;
}
else {
vTop = vJQElement.position().top + 25;
vLeft = vJQElement.position().left;
}
//Create div element
var vDivElement = $("<div id='divSearchBox' style='position:absolute; top:" + vTop + ";left:" + vLeft + "; z-index: 40000;'></div>");
//Create list box
var vListBox = $("<select id='lbResults' tabIndex='" + vJQElement.attr("tabIndex") + "' size='4' style='height:400px;'></select>");
//Bind a function to the list box which will select the item via either tab or enter
vListBox.bind("keydown", function() {
//Check if tab or enter has been pressed
if (event.keyCode == 9 || event.keyCode == 13) {
//Set hidden value to the selected items code
$(vHiddenFieldToWriteTo).val($(vListBox.find(":selected")).val());
//Create postback
$('#ctl00_ContentPlaceHolder1_wizNewConsignment_btnRefresh').click();
}
//Check if the up arrow has been pressed at the top of the listbox
else if (event.keyCode == 38 && $(vListBox.find(":selected")).val() == $(vListBox.find(":first")).val()) {
//Focus back on the search box
vElement.focus();
}
}).bind("dblclick", function() {
//Set hidden value to the selected items code
$(vHiddenFieldToWriteTo).val($(vListBox.find(":selected")).val());
//Create postback
$('#ctl00_ContentPlaceHolder1_wizNewConsignment_btnRefresh').click();
});
//Get search field
var vSearchText = vJQElement.val();
var vDepotID = $("#ctl00_ContentPlaceHolder1_wizNewConsignment_hfDepotID").val();
var vCustomerID = $("#ctl00_ContentPlaceHolder1_wizNewConsignment_hfCustomerID").val();
var vCountryID = $("#ctl00_ContentPlaceHolder1_wizNewConsignment_hfCountryID").val();
var vConsignee = vJQElement.attr("boolConsignee");
//Set a loading image in place until call completed
vJQElement.css("backgroundImage", "url(images/small-loader.gif)");
vJQElement.css("backgroundRepeat", "no-repeat");
vJQElement.css("backgroundPosition", "right");
//Make AJAX call
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "NewConsignment.asmx/fGetAddressesAndIDs",
data: "{'strSearchText' : '" + vSearchText + "', 'intDepotID' : '" + vDepotID + "', 'intCustomerID' : '" + vCustomerID + "', 'intCountryID' : '" + vCountryID + "', 'boolConsignee' : '" + vConsignee + "'}",
dataType: "json",
success: function fGetAddressesAndIDsResult(GetAddressesAndIDsResult) {
//Make sure there are results
if (GetAddressesAndIDsResult != null && GetAddressesAndIDsResult != "") {
var vNumberOfResults = 0;
var vNumberOfLearntAddresses = 0;
var vLearntAddressUniqueID = "";
//Try to get results (first call will work on Linux and catch will work on Windows)
try {
//Check array exists (if this fails will go to catch)
if (GetAddressesAndIDsResult.d.length > 0) {
//Loop through the results
$.each(GetAddressesAndIDsResult.d, function() {
//Check for results
if (this.length > 0) {
//Evaluate JSON
var vAddress = eval("(" + this + ")");
//Create list item
var vOption = $("<option class='AddressOption' value='" + vAddress.uniqueID + "'>" + vAddress.briefDescription + "</option>");
//Find out number of learnt addresses
if (vAddress.uniqueID.indexOf("ConLA") != -1) {
vNumberOfLearntAddresses++;
vLearntAddressUniqueID = vAddress.uniqueID;
}
//Add list item to list box
vListBox.append(vOption);
//Mark result added
vNumberOfResults++;
}
});
}
}
catch (err) {
//Loop through the results
$.each(GetAddressesAndIDsResult, function() {
//Check for results
if (this.length > 0) {
//Evaluate JSON
var vAddress = eval("(" + this + ")");
//Create list item
var vOption = $("<option class='AddressOption' value='" + vAddress.uniqueID + "'>" + vAddress.briefDescription + "</option>");
//Find out number of learnt addresses
if (vAddress.uniqueID.indexOf("ConLA") != -1) {
vNumberOfLearntAddresses++;
vLearntAddressUniqueID = vAddress.uniqueID;
}
//Add list item to list box
vListBox.append(vOption);
//Mark result added
vNumberOfResults++;
}
});
}
//Check if only 1 learnt address was found
if (vNumberOfLearntAddresses == 1) {
//Auto select this address
//Set hidden value to the selected items code
$(vHiddenFieldToWriteTo).val(vLearntAddressUniqueID);
//Create postback
$('#ctl00_ContentPlaceHolder1_wizNewConsignment_btnRefresh').click();
}
//Add list box to div
vDivElement.append(vListBox);
//Check if any results exist in div
if (vNumberOfResults != 0) {
//Append div to page
$("body").append(vDivElement);
//Auto select first item
vListBox.find(".AddressOption:first").attr("selected", "true");
}
}
//Hide loading image
vJQElement.css("backgroundImage", "none");
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
//Inform user of error
alert("An error occured, please try again");
//Hide loading image
vJQElement.css("backgroundImage", "none");
}
});
}
}
Try this:
setTimeout(function() { fDelayedFunc(); }, 0);
I took setTimeout(function () {function1();}, 1500) out from the addEventListener("load", () => {code})
it worked for me inside Firefox
try this : setTimeout('fDelayedFunc()', 0);