loop through selected checkboxes - javascript

In the checkboxes which pertains on the same class ,I'm using this function (not finished) tho loop and set a string
function estados() {
var query = "trucades.estat in(";
var checks = $('.estate_check:checked');
if (checks.length === 0) {
query = "not selected ";
} else {
//set the message here ...but only loops once
}
return query;
}
But checks only contains an object which contains the selected checkboxes but if I try to llop ,it only loops once ,because only contains this object

var ckbox = $('.my-checkbox:checked');
var str = "";
ckbox.each(function(){
str += $(this).attr('data-text') + ", ";
});
alert(str);
This fiddle helps you figure it out:
JSFiddle

Assuming you need to create query, You can use .map() along with .get() to create an array of selected values. then Array.join() can be used to create comma separated string.
function estados() {
var query = "trucades.estat in(";
var checks = $('.estate_check:checked');
if (checks.length === 0) {
query = "not selected ";
} else {
//Create an array of selected value
var selectedValue = checks.map(function () {
return $(this).val();
}).get();
query += selectedValue.join(',') + ')'
}
return query;
}

function estados() {
var query = "trucades.estat in(";
$('.estate_check:checked').each(function( index ) {
const val = $( this ).val()
console.log(index + ': ' + val);
query += val;
});
query += ')';
return query;
}

Related

String array with key and value Remove already exist

I found some similar questions, but none helped me.
I have an array, and I am pushing items into it. I want to check if there is already an item then removes and add a new value.
I am doing this in the success of an ajax call,
var taxSplitUp = []; // my array
// ajax call here, in the success
for (var i in data.d) {
var ItemTaxAmt= data.d[i].ItemTaxAmt;
var TaxName = data.d[i].TaxName;
var idx = $.inArray(TaxName, taxSplitUp); // checks if already exist
if (idx == -1) {
var tx1 = '{"' + TaxName + '":"' + parseFloat(ItemTaxAmt).toFixed(2) + '"}';
taxSplitUp.push(tx1);
}
else {
taxSplitUp.splice(idx, 1); // removing
var t1 = taxSplitUp[TaxName]; // selecting the value from array
var tx1 = '{"' + TaxName + '":"' + parseFloat(ItemTaxAmt).toFixed(2) + parseFloat(t1).toFixed(2) + '"}';
taxSplitUp.push(tx1);
}
}
Here if the same key came, then I want to add the values together and want only one in the array, but the checking always returns false and adds another into the array.
please help.
$.inArray wont work with associative array. Try below solution
for (var i in data) {
var ItemTaxAmt= data[i].ItemTaxAmt;
var TaxName = data[i].TaxName;
console.log(TaxName);
$.map(taxSplitUp, function(item, index) {
if (item.TaxName == TaxName) {
item.ItemTaxAmt = ItemTaxAmt;
}else{
taxSplitUp.push({
'TaxName' :TaxName,
'ItemTaxAmt' : ItemTaxAmt
});
}
});
}
console.log(taxSplitUp);

JavaScript - Function for finding text within a string

I have a function that I use to pass over a table field name and its value. Depending on the name of the field, it either returns the contents as a link or it does not.
// Given a field name, check to see if its in our output. If so, return the formatted link
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for ( i = 0; i < keys.length; ++i ) {
key = keys[i];
if(field.toLowerCase() == key){
return ''+val+'';
}
}
return val;
}
Usage:
createLink('email', 'bob#stuff.com')
// returns bob#stuff.com
This also works for NTID. The issue I am having though is there are some field names that contain my values in the output such as Sup Email or Sup NTID and those are not transformed correctly.
Expected Result:
createLink('sup email', 'bob2#stuff2.com')
// returns bob#stuff.com
The Question:
How can I tweak my function to see if my field exists in the output array at all, even if it's not an exact match?
Change your function to
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if ((field.toLowerCase()).includes(key)) {
return '' + val + '';
}
}
return val;
}
console.log(createLink('sup email', 'bob2#stuff2.com') )
Notice the code if ((field.toLowerCase()).includes(key)) {
This will check for your key substring in the string
What you're implementing is the Strategy Pattern. The Strategy Pattern relies on some form of behaviour-switching depending on the inputs to the method. In your case, that switching is based on the first argument.
What you don't want to do is what your questions asks how to do. You don't want to assume every field name in your application which contains "email" or some other string is guaranteed to be an email address, handled by the same strategy.
Create a table of field names and strategies to use for the display of each of these fields; and use an "enum-ish" object as the definition of the strategies.
function create_link(field, val) {
const strategy = create_link.Field_Strategies[field];
if (typeof strategy === 'undefined') {
console.log("Using default strategy");
return val;
}
console.log("Using " + strategy);
switch (strategy) {
case create_link.Strategies.EMAIL:
return '' + val + '';
case create_link.Strategies.NTID:
return '<a href="https://web.internal/profile/' +
val + '" target="_blank">' + val + '</a>';
case create_link.Strategies.SOME_FIELD:
return '<a href="http://example.com/some/path/' +
encodeURIComponent(val) +
'" target="_blank">' + val + '</a>';
}
}
create_link.Strategies = {
EMAIL: "email strategy",
NTID: "ntid strategy",
SOME_FIELD: "somefield strategy"
};
create_link.Field_Strategies = {
"Sup email": create_link.Strategies.EMAIL,
"E-mail": create_link.Strategies.EMAIL,
"Email": create_link.Strategies.EMAIL,
"NTID": create_link.Strategies.NTID,
"Foobar baz": create_link.Strategies.SOME_FIELD
};
console.log(create_link("foo","foofoofoo"));
console.log(create_link("Sup email","supervisor#example.com"));
console.log(create_link("E-mail","foo#example.com"));
console.log(create_link("Email","bar#example.com"));
console.log(create_link("NTID","10983409509734"));
console.log(create_link("Foobar baz","Aleph null"));
You could use String.prototype.indexOf.
The indexOf() method returns the index within the calling String object of the first occurrence of the specified value...Returns -1 if the value is not found.
So your code would then look like:
// Given a field name, check to see if its in our output. If so, return the formatted link
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for ( i = 0; i < keys.length; ++i ) {
key = keys[i];
if(field.toLowerCase().indexOf(key) >= 0){ //CHANGE HERE
return ''+val+'';
}
}
return val;
}

JSON return value to global variable

Simply my code looks like this:
var thevariable = 0;
For(){
//somecode using thevariable
$.getJSON('',{},function(e){
//success and i want to set the returned value from php to my variable to use it in the forloop
thevariable = e.result;
});
}
my main problem that the variable value stays "0", during the whole For loop, while i only want it to be "0" at the first loop, then it takes the result returned from PHP to use it on for loop.
here it my real code if you need to take a look:
var orderinvoice = 0;
for(var i=0; i<table.rows.length; i++){
var ordername = table.rows[i].cells[5].innerText;
var orderqty = ((table.rows[i].cells[1].innerText).replace(/\,/g,'')).replace(/Qty /g,'');
var orderprice = (table.rows[i].cells[2].innerText).replace(/\$/g,'');
var ordertype = table.rows[i].cells[3].innerText;
var orderlink = table.rows[i].cells[4].innerText;
$.getJSON('orderprocess.php', {'invoice': orderinvoice, 'pay_email': email, 'ord_name': ordername, 'ord_qty': orderqty, 'ord_price': orderprice, 'ord_type': ordertype, 'ord_link': orderlink}, function(e) {
console.log();
document.getElementById("result").innerText= document.getElementById("result").innerText + "Order #"+e.result+" Created Successfully ";
document.getElementById("invoker").innerText = ""+e.invoice;
orderinvoice = e.invoice;
if(i+1 == table.rows.length){
document.getElementById("result").innerText= document.getElementById("result").innerText + "With invoice #" + e.invoice;
}
});
in a loop block, before one ajax complete other one will be run and this's javascript natural treatment. For your case you can call a function at the end of success event. Do something like this:
var i = 0;
doSt();
function doSt() {
var orderinvoice = 0;
var ordername = table.rows[i].cells[5].innerText;
var orderqty = ((table.rows[i].cells[1].innerText).replace(/\,/g, '')).replace(/Qty /g, '');
var orderprice = (table.rows[i].cells[2].innerText).replace(/\$/g, '');
var ordertype = table.rows[i].cells[3].innerText;
var orderlink = table.rows[i].cells[4].innerText;
$.getJSON('orderprocess.php', { 'invoice': orderinvoice, 'pay_email': email, 'ord_name': ordername, 'ord_qty': orderqty, 'ord_price': orderprice, 'ord_type': ordertype, 'ord_link': orderlink }, function(e) {
console.log();
document.getElementById("result").innerText = document.getElementById("result").innerText + "Order #" + e.result + " Created Successfully ";
document.getElementById("invoker").innerText = "" + e.invoice;
orderinvoice = e.invoice;
if (i + 1 == table.rows.length) {
document.getElementById("result").innerText = document.getElementById("result").innerText + "With invoice #" + e.invoice;
}
i++;
if (i < table.rows.length) doSt();
});
}
I think you need a recursive function that always deals with the first element in your rows array and then splices it off and calls itself. For example, something like this:
function getStuff(rows, results) {
if (rows.length > 0) {
var ordername = rows[0].cells[5].innerText;
$.getJSON('orderprocess.php', { 'ord_name': ordername }, function (e) {
// do some stuff
results.push('aggregate some things here?');
rows.splice(0, 1);
return getStuff(rows, results);
});
} else {
return results;
}
}
When the array is spent, results will be returned with whatever aggregate you wanted at the end of the cycle. Then, you can do as you please with the results. I think you can also manipulate the DOM inside the function as you see fit if that makes more sense. Hope this helps.

Stopping the Jquery.map when a condition is met

I have the following code:
var parentEls = node.parents()
.map(function () {
var curParentID = this.getAttribute("id");
var curParentClass = this.getAttribute("class");
if(curParentID) {
return this.tagName + "#" + curParentID;
/*stop the map function from proceeding*/
} else {
return this.tagName;
}
})
.get().reverse().join(", ");
The above code helps to find search for unique id and once an ID is spotted , it creates the xpath. How can i stop the the map function once it has come to a point where the id is retrieved and the map function should stop? I tried return false and break but it does not work.
Is there any other suggestion?
I don't think it is possible using .map(), you may have to use .each() here
var temp = [];
node.parents().each(function () {
var curParentID = this.getAttribute("id");
var curParentClass = this.getAttribute("class");
if(curParentID){
temp.push(this.tagName + "#" + curParentID);
return false;
} else {
temp.push(this.tagName);
}
});
var parentEls = temp.reverse().join(", ");
// parentsUntil() doesn't include the element specified by selector,
// so you need to add the closest ancestor with id attribute to the collection
var parentEls = node.parentsUntil('[id]').add( node.closest('[id]') )
.map(function () {
return this.id ? '#' + this.id : this.tagName;
})
.get().join(", ");
Fiddle (updated): http://jsfiddle.net/SKqhc/5/

Modify javascript code to iterate through all variables in the form

I have the following code that worked fine till now as I decided to add more variables to the form. How can I make this function smart and itterate and pass all the variables in the form?
function getquerystring(strFormName) {
var form = document.forms[strFormName];
var word = form.clock_code.value;
qstr = 'clock_code=' + escape(word); // NOTE: no '?' before querystring
return qstr;
}
complete JS code # pastie
It looks like you're serializing a form to a querystring? If that's the case, then this is one place where a JavaScript library is really nice.
Each of these will serialize the first form on the page to a querystring.
// ExtJS
var str = Ext.lib.Ajax.serializeForm(Ext.select('form').elements[0]);
// jQuery
var str = $("form").serialize();
// MooTools
var str = $$('form').toQueryString();
// PrototypeJS
var str = $$('form')[0].serialize();
You can see some other methods and how they compare at http://jquery.malsup.com/form/comp/
Try this
function formToQueryString(form) {
var elements = form.elements;
var cgi = [];
for (var i = 0, n = elements.length; i < n; ++i) {
var el = elements[i];
if (!el.name) { continue; }
if (el.tagName === 'INPUT' && (el.type === 'checkbox' || el.type === 'radio')
&& !el.checked) {
continue;
}
cgi.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value));
}
return cgi.length ? '?' + cgi.join('&') : '';
}
The issue with your code is that you're only grabbing the clock_code element value, and ignoring the rest. Here's a replacement I wrote up:
function getquerystring(strFormName) {
var qstr = '', word = '';
var key = 0;
var form = document.forms[strFormName];
var fields = ['clock_code', 'message', 'type'];
for (var i = 0; i<fields.length; i++) {
key = fields[i];
word = form[key].value;
if (qstr && qstr.length > 0) {
qstr += '&';
}
qstr += encodeURIComponent(key) + '=' + encodeURIComponent(word);
}
return qstr;
}
Benjamin's approach is a bit more flexible; mine only queries those fields specifically named in the fields array
Assuming they are all simple fields, the following should work just fine (didn't test it, though - sorry if it doesn't "compile"):
function getquerystring(strFormName) {
var qstr = '';
var form = document.forms[strFormName];
var elements = form.elements;
var first = true;
for (elem in elements) {
var word = elem.value;
var name = elem.name;
if (first) {
first = false;
} else {
qstr = qstr + '&';
}
qstr = qstr + name + '=' + escape(word);
}
return qstr;
}
Adding info on supporting multiple Element types:
The question only mentioned text fields so I assumed the easier answer would suffice. Wrong!
Glad you're able to use JQuery (which rocks), but for completeness I'll just flesh this out with a bit of info on how to build your own "dynamic form handler".
First, you have to add checking on the class of elem, like so:
function isCheckbox(o){ return (o && o.constructor == Checkbox) }
and you have to then do something a little different depending on the type of object you are looking at.
For example:
for (var elem in elements) {
var value = '';
var name = elem.name;
if (isCheckbox(elem)) {
value = elem.checked ? 'true' : 'false';
} else if (isSingleSelect(elem)) {
var index = elem.selectedIndex;
if(selected_index > 0) {
value = elem.options[selected_index].value;
}
}
}
There may be situations where you have to turn values into something that is meaningful to your app, like in a multiple-select combo box. You could send one name=value pair for each value or roll them into a comma-seperated list or the like - it all depends on your app. But with this approach one can certainly build the "dynamic form handler" that fits their specific needs.
Check out this article for helpful stuff about how to process each form field type: http://www.javascript-coder.com/javascript-form/javascript-get-form.htm

Categories

Resources