how to do a search with an array - javascript

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.

Related

How to use higher order functions instead of FOR Loop for Line items in Suitelet printouts (Netsuite)?

i have been tasked by my senior to print values of line items using higher order functions (.filter/.map/.reject/.reduce). I m confused how to write the higher order function instead of a for loop(for printing the line values in Invoice Printout). I need to print the line only when the qty is more than 3. I m an intern and i dont know how it will work, kindly help.
Link to The code snippet: https://drive.google.com/file/d/1uVQQb0dsg_bo53fT3vk9f0G8WwZomgQg/view?usp=sharing
I always used if condition for printing the row only when the quantity field has value more than 3. I even know how to .filter but i dont know how to call it and where to call it. Please help
I don't believe Array.from works in server side code. If it does then use that. What I have been using are the following functions. They don't conform to the higher order functions specified but they work with Netsuite syntax and go a long way towards simplifying sublist handling and encapsulating code:
//SS2.x
//I have this as a snippet that can be included in server side scripts
function iter(rec, listName, cb){
var lim = rec.getLineCount({sublistId:listName});
var i = 0;
var getV = function (fld){
return rec.getSublistValue({sublistId:listName, fieldId:fld, line:i});
};
for(; i< lim; i++){
cb(i, getV);
}
}
// to use it:
iter(ctx.newRecord, 'item', function(idx, getV){
if(parseInt(getV('quantity')) >3){
...
}
});
or for SS1 scripts I have the following which allows code to be shared between UserEvent and Scheduled scripts or Suitelets
function forRecordLines(rec, machName, op, doReverse) {
var i, pred, incr;
var getVal = rec ? function(fld) {
return rec.getLineItemValue(machName, fld, i);
} : function(fld) {
return nlapiGetLineItemValue(machName, fld, i);
};
var getText = rec ? function(fld) {
return rec.getLineItemText(machName, fld, i);
} : function(fld) {
return nlapiGetLineItemText(machName, fld, i);
};
var setVal = rec ? function(fld, val) {
rec.setLineItemValue(machName, fld, i, val);
} : function(fld, val) {
nlapiSetLineItemValue(machName, fld, i, val);
};
var machCount = rec ? rec.getLineItemCount(machName) : nlapiGetLineItemCount(machName);
if(!doReverse){
i = 1;
pred = function(){ return i<= machCount;};
incr = function(){ i++;};
}else{
i = machCount;
pred = function(){ return i>0;};
incr = function(){ i--;};
}
while(pred()){
var ret = op(i, getVal, getText, setVal);
incr();
if (typeof ret != 'undefined' && !ret) break;
}
}
// User Event Script:
forRecordLines(null, 'item', function(idx, getV, getT, setV){
if(parseInt(getV('quantity')) >3){
...
}
});
// in a Scheduled Script:
forRecordLines(nlapiLoadRecord('salesorder', id), 'item', function(idx, getV, getT, setV){
if(parseInt(getV('quantity')) >3){
...
}
});
Usually its a straight forward task, but since you are getting length and based on that you are iterating, you can use Array.from. Its signature is:
Array.from(ArrayLikeObject, mapFunction);
var tableData = Array.from({ length: countItem}, function(index) {
vendorBillRec.selectLineItem('item', index);
var item = vendorBillRec.getCurrentLineItemText('item', 'item');
var description = nlapiEscapeXML(vendorBillRec.getCurrentLineItemValue('item', 'description'));
var quantity = parseFloat(nullNumber(vendorBillRec.getCurrentLineItemValue('item', 'quantity')));
return { item, description, quantity}
});
var htmlData = tableData.filter(...).map(getRowMarkup).join('');
function getRowMarkup(data) {
const { itemName, descript, quantity } = data;
return '<tr>' +
'<td colspan="6">' +
'<p>' + itemName + ' ' + descript + '</p>'+
'</td>' +
'<td colspan="2" align="right">' + quantity + '</td>' +
'</tr>';
}
Or if you like to use more functional approach:
Create a function that reads and give you all data in Array format. You can use this data for any task.
Create a function that will accept an object of specified properties and returns a markup.
Pass the data to this markup after any filter condition.
Idea is to isolate both the task:
- Getting data that needs to be processed
- Presentation logic and style related code
var htmlString = Array.from({ length: countItem}, function(index) {
vendorBillRec.selectLineItem('item', index);
var item = vendorBillRec.getCurrentLineItemText('item', 'item');
var description = nlapiEscapeXML(vendorBillRec.getCurrentLineItemValue('item', 'description'));
var qty = parseFloat(nullNumber(vendorBillRec.getCurrentLineItemValue('item', 'quantity')));
return getRowMarkup(item, description, qty)
}).join('');
function getRowMarkup(itemName, descript, quantity) {
return '<tr>' +
'<td colspan="6">' +
'<p>' + itemName + ' ' + descript + '</p>'+
'</td>' +
'<td colspan="2" align="right">' + quantity + '</td>' +
'</tr>';
}

Sort div array based on alphabets during appending Jquery

I am stuck in a place where I have to sort the list of names when moved those list on button click.
sort()
method works fine but clicking on the same button again creating duplicates!, which is not I need.
Is there any way I can fix this. used below code too(which took from stackoverflow) even this is not working.
function SortByName(a, b) {
var aName = a.name.toLowerCase();
var bName = b.name.toLowerCase();
return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
}
var selectArr = selectedList.sort(SortByName);
MY CODE
$(document).on('click', '#buttonAdd', function (e) {
var divCount = $('#SelectedEmployeeList').find('div').length;
if (divCount === 0) {
selectedList = []; // Clearing the list, to add fresh employee list.
}
$('#EmployeeList :selected').each(function (i, selected) {
selectedList[$(selected).val()] = $(selected).text();
});
// Returning DOM node from collection.
var empListNode = $("#SelectedEmployeeList")[0];
console.log(empListNode);
while (empListNode.firstChild) {
empListNode.removeChild(empListNode.firstChild);
}
for (var empID in selectedList) {
$("#SelectedEmployeeList").append("<div class= EmpList id=" + empID + ">" + selectedList[empID] + " <span class='close'>×</Span> </div>");
}
});
This is the place where all sort should happen #SelectedEmployeeList.
have shared the pics for references.
Sort is happening correctly on the left like here :
after clicking on "Add All >> " items are moved but not sorted :
any help will be appreciated.
UPDATE 1 :
This is your problem:
for (var empID in selectedList) {
$("#SelectedEmployeeList").append("<div class= EmpList id=" + empID + ">" + selectedList[empID] + " <span class='close'>×</Span> </div>");
}
For...in iterates over an object in no order. Save your employees in an array and iterate over it:
var selectedList = [];
$('#EmployeeList :selected').each(function (i, selected) {
// push an object into the selectedList array
selectedList.push({
empID : $(selected).val(),
text: $(selected).text(),
div: selected
});
});
// iterate over the array in order
for (var i = 0; i < selectedList.length; i++) {
// appends a NEW div
$("#SelectedEmployeeList").append("<div class= EmpList id=" + selectedList[i].empID + ">" + selectedList[i].text + " <span class='close'>×</Span> </div>");
// MOVES the div
$("#SelectedEmployeeList").append(selectedList[i].div);
}

Verify if data already in db, with more inputs same class

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
});

post data from table row like json format

this is related to my last question(
NOTE: I already got some good answers there). I'm doing a program that will filter. I didn't include this question because i thought that it is easier for me to add text as long as i know how to get the data from the row. But to my dismay, I wasn't able to code a good program til now.
Im currently using this javascript code (thanks to Awea):
$('#out').click(function(){
$('table tr').each(function(){
var td = '';
$(this).find('option:selected').each(function(){
td = td + ' ' + $(this).text();
});
td = td + ' ' + $(this).find('input').val();
alert(td);
});
})
my question is: How to add text before the data from the row? like for example, this code alert
the first row like data1.1 data1.2 data1.3,
then the second row like data2.1 data2.2 data2.3,
I want my output to be displayed like this
[
{"name":"data1.1","comparison":"data1.2", "value":"data1.3"},
{"name":"data2.1","comparison":"data2.2", "value":"data2.3"},
{"name":"data3.1","comparison":"data3.2", "value":"data3.3"}
{.....and so on......}]
but before that happen, i want to check if all the FIRST cell in a row is not empty. if its empty, skip that row then proceed to next row.
is there somebody can help me, please...
Building on my answer to your previous question, see http://jsfiddle.net/evbUa/1/
Once you have your data in a javascript object (dataArray in my example), you can write the JSON yourself, per my example, but you will find it much easier to use a library such as JSON-js (see this also).
// object to hold your data
function dataRow(value1,value2,value3) {
this.name = value1;
this.comparison = value2;
this.value = value3;
}
$('#out').click(function(){
// create array to hold your data
var dataArray = new Array();
// iterate through rows of table
for(var i = 1; i <= $("table tr").length; i++){
// check if first field is used
if($("table tr:nth-child(" + i + ") select[class='field']").val().length > 0) {
// create object and push to array
dataArray.push(
new dataRow(
$("table tr:nth-child(" + i + ") select[class='field']").val(),
$("table tr:nth-child(" + i + ") select[class='comp']").val(),
$("table tr:nth-child(" + i + ") input").val())
);
}
}
// consider using a JSON library to do this for you
for(var i = 0; i < dataArray.length; i++){
var output = "";
output = output + '{"name":"data' + (i + 1) + '.' + dataArray[i].name + '",';
output = output + '"comparison":"data' + (i + 1) + '.' + dataArray[i].comparison + '",';
output = output + '"value":"data' + (i + 1) + '.' + dataArray[i].value + '"}';
alert(output);
}
})
There are two things you need to do here. First get the data into an array of objects, and secondly get the string representation.
I have not tested this, but it should give you a basic idea of what to do.
Edit Please take a look at this JS-Fiddle example I've made. http://jsfiddle.net/4Nr9m/52/
$(document).ready(function() {
var objects = new Array();
$('table tr').each(function(key, value) {
if($(this).find('td:first').not(':empty')) {
//loop over the cells
obj = {};
$(this).find('td').each(function(key, value) {
var label = $(this).parents('table').find('th')[key].innerHTML;
obj[label] = value.innerHTML;
});
objects.push(obj);
}
});
//get JSON.
var json = objects.toSource();
$('#result').append(json);
});
var a = [];
a[0] = "data1.1 data1.2 data1.3"
a[1] = "data1.6 data1.2 data1.3"
var jsonobj = {};
var c = []
for (var i = 0;i
alert(c); //it will give ["{"name":"data1.1","comp...1.2","value":"data1.3"}", "{"name":"data1.6","comp...1.2","value":"data1.3"}"]
u have to include library for function from JSON.stringify from
https://github.com/douglascrockford/JSON-js/blob/master/json2.js
hope this helps

Javascript challenge. How do I achieve this with arrays?

Let's say I have:
var directions = [ "name", "start_address", "end_address", "order_date" ];
I'm trying to find a slick, fast way to turn that array into this:
data: {
"directions[name]" : directions_name.val(),
"directions[start_address]" : directions_start_address.val(),
"directions[end_address]" : directions_end_address.val(),
"directions[order_date]" : directions_order_date.val()
}
Notice the pattern. The name of the array "directions" is the prefix to the values.
I'm interested how people can either do this or at least suggest a way for me to try.
Any tips would be appreciated.
Thanks!
EDIT **
Thanks for the suggestions so far. However, I forgot to mention that the array "directions" needs to be dynamic.
For example, I could use:
places = ["name", "location"]
should return
data: {
"places[name]" : places_name.val(),
"places[location]" : places_location.val()
}
alpha = ["blue", "orange"]
should return
data: {
"alpha[blue]" : alpha_blue.val(),
"alpha[orange]" : alpha_orange.val()
}
So basically I could just pass an array into a function and it return that data object.
var directions = ["name", "start_address", .... ];
var data = someCoolFunction( directions );
Hope that makes sense.
** EDIT **************
I want to thank everyone for their help. I ended up going a different route. After thinking about it, I decided to put some meta information in the HTML form itself. And, I stick to a naming convention. So that an HTML form has the information it needs (WITHOUT being bloated) to tell jQuery where to POST the information. This is what I ended up doing (for those interested):
// addBox
// generic new object box.
function addBox(name, options) {
var self = this;
var title = "Add " + name.charAt(0).toUpperCase() + name.slice(1);
var url = name.match(/s$/) ? name.toLowerCase() : name.toLowerCase() + "s";
allFields.val(""); tips.text("");
$("#dialog-form-" + name).dialog( $.extend(default_dialog_options, {
title: title,
buttons: [
{ // Add Button
text: title,
click: function(){
var bValid = true;
allFields.removeClass( "ui-state-error" );
var data = {};
$("#dialog-form-" + name + " input[type=text]").each(function() { // each is fine for small loops :-)
var stripped_name = this["name"].replace(name + "_", "");
data[name + "[" + stripped_name + "]"] = $("#dialog-form-" + name + " #" + name + "_" + stripped_name).val();
});
// verify required fields are set
$("#dialog-form-" + name + " input[type=text].required").each(function() {
bValid = bValid && checkLength( $(this), $(this).attr("name").replace("_", " "), 3, 64 );
});
// find sliders
$("#dialog-form-" + name + " .slider").each( function() {
data[name + "[" + $(this).attr("data-name") + "]"] = $(this).slider( "option", "value" );
});
data["trip_id"] = trip_id;
if(options != null) { $.extend(data, options); } // add optional key/values
if(bValid) {
$(".ui-button").attr("disabled", true);
$.ajax( { url : "/" + url, type : "POST", data : data } );
}
}
},
{ text: "Cancel", click: function(){$( this ).dialog( "close" );} }
]
}));
}
It's really unclear what you want here. Perhaps you should give the interface to the function you want, and an example of some code which sets up some sample variables and calls the function.
What you seem to be asking for is to dynamically find variables which you have already declared in the environment, such as directions_name and directions_start_address, and call the val() method on each of them, then construct a dictionary mapping strings to those results. But the keys of the dictionary contain JavaScript syntax. Are you sure that's what you want?
function transform(name)
{
var data = {};
var names = window[name];
for (var i=0; i<names.length; i++)
{
data[name + "[" + names[i] + "]"] = window[name + "_" + names[i]].val();
}
return data;
}
Edit: To use JQuery to look up objects by ID instead of the above approach (which looks up global variables by name):
function transform(name)
{
var data = {};
var names = $("#" + name);
for (var i=0; i<names.length; i++)
{
data[name + "[" + names[i] + "]"] = $("#" + name + "_" + names[i]).val();
}
return data;
}
This will look up the name in the global space of the window (which will work in a browser anyway). You call that function with "directions" as the argument. For example:
var directions = [ "name", "start_address", "end_address", "order_date" ];
var directions_name = {"val": function() {return "Joe";}};
var directions_start_address = {"val": function() {return "14 X Street";}};
var directions_end_address = {"val": function() {return "12 Y Street";}};
var directions_order_date = {"val": function() {return "1/2/3";}};
data = transform("directions");
Is that what you want?
(Note: I see someone else posted a solution using $ and "#" ... I think that's JQuery syntax, right? This works without JQuery.)
Edit: Note that this lets you use a dynamic value for "directions". But I'm still not sure why you want those keys to be "directions[name]", "directions[start_address]", instead of "name", "start_address", etc. Much easier to look up.
Edit: I fixed my sample code to use functions in the values. Is this really what you want? It would be easier if you weren't calling val() with parens.
Like this:
var data = { };
for(var i = 0; i < directions.length; i++) {
var name = directions[i];
data["directions[" + name + "]"] = $('#directions_' + name).val();
}
Or,
data["directions[" + name + "]"] = directionsElements[name].val();
EDIT: You can pass an array and a prefix.

Categories

Resources