Passing selected options as an array using ajax - javascript

I have a contact list as below:
<div class="contacts_list_data_contacts" id="contactlist">
<div class="contacts_checkbox_01"><input name="contact_id[]" id="contact_id" type="checkbox" value="28383" style="margin-top:0px ; margin-left:-3px;" /></div>
<div class="contacts_firstname_01_contacts">Michael</div>
<div class="ncontacts_mobile_nmbr_01">+44515665544</div>
</div>
<div class="contacts_list_data_contacts" id="contactlist">
<div class="contacts_checkbox_01"><input name="contact_id[]" id="contact_id" type="checkbox" value="28383" style="margin-top:0px ; margin-left:-3px;" /></div>
<div class="contacts_firstname_01_contacts">Katherine</div>
<div class="ncontacts_mobile_nmbr_01">+30589746621</div>
</div>
It looks like that:
Firstname MobileNumber
===========================
Michael +44515665544
Katherine +30589746621
I am using ajax request to delete a contact
contact_id=document.getElementById('contact_id_ajax').value;
xmlHttp.open("POST","?action=ajaxcontact&todo=DeleteContact&contact_id=" +contact_id ,true);
Using the below function I am able to get ONLY one contact at once by put a checkbox. I don't know how to pass all of the contacts when I select all the contacts and pass them to the ajax request.
<Script>
var field;
function get_contact(field)
{
for (i = 0; i < field.length; i++)
if(field[i].checked)
document.getElementById("contact_id_ajax").value=field[i].value;
}
</Script>
Thank you,

First things, first. You have a lot places where you use the same IDs for elements. This is very bad practice indeed. IF you want a way to identify a collection of similar items, use classes (you already have - just get rid of the ids or get unique ones).
Now, if you add a class to your checkboxes like so -
<input name="contact_id[]" class="contact_id" type="checkbox" value="28383" style="margin-top:0px ; margin-left:-3px;" />
Then in your getContacts function, you can skip the argument and go with -
function getContacts(){
var contacts = document.getElementByClassName('contact_id'), ids = [];
for (var i = 0; i < contacts.length; i += 1){
if (contacts[i].checked)
ids.push(contacts[i].value);
}
return ids;
}
Now, when you want the contacts list -
var contacts = getContacts(); //array of contact ids
//This array can now be used in your ajax request

Related

Protractor AngularJS count, copy, and verify a list span

I am new to automated testing, Protractor, and angularJS. I have a list that I would like to count, copy to an array maybe, and verify the list text is present. For example The list shows Attractions, Capacity, and Content to the user so they know what privileges they have.
Below is the .html
<div class="home-info">
<div class="home-top home-section">
<h3>User Information</h3>
<div class="home-box">
<div class="property-group wide">
<span>
Change Phillips<br />
</span>
</div>
</div>
<div class="home-box">
<div class="property-group wide">
<div>Editors:</div>
<span>
<ul class="property-stack">
<li><span>Attractions</span>
</li>
<li><span>Capacity</span>
</li>
<li><span>Content</span>
</li>
<li><span>Media</span>
</li>
<li><span>Options</span>
</li>
<li></li>
<li></li>
<li><span>Upload CADs</span>
</li>
</ul>
</span>
</div>
</div>
</div>
Below is the code I have written. I can get the first item on the list however using .all isn't working for me.
var text = "";
browser.driver.findElement.all(By.xpath("//li/span")).count().then(function(count) {
initialCount = count;
console.log(initialCount);
});
browser.driver.findElement(By.xpath("//li/span")).getText().then(function(text) {
console.log(text);
});
I'm trying to avoid using xpath as I was told to try and avoid. To be honest Im lost. Thanks for the help in advance.
Code used for matching:
expect(myLists).toEqual(['Attractions', 'Capacity', 'Conent',
'Media', 'Options', 'Upload CADs'
]);
I am not sure what version of protractor you're using but you should be able to just call element without the browser or driver prefix. Using element.all should get you the array of of elements you're looking for.
If you want to access specific indexes within that array you can use the .get(index) suffix to the element.all
So below:
1. you get the array of the elements
2. you get the count of the array
3. we call a for loop to iterate through all the indexes of the array
4. each index of the array we call the getText() and print it to the console
var j = 0; // using this since the i iterator in the for loop doesn't work within a then function
var textList = [];
var text = "";
var myLists = element.all(by.css("li span"));
myLists.count().then(function(count) {
console.log(count);
for(int i = 0; i < count; i++){
myLists.get(i).getText().then(function(text) {
textList[j++] = text;
console.log(text);
});
}
});
EDIT:
In researching I actually found another way to iterate through the array of elements by using the .each() suffix to the element.all.
var j = 0; // using this since the i iterator in the for loop doesn't work within a then function
var textList = [];
var text = "";
var myLists = element.all(by.css("li span"));
myLists.count().then(function(count) {
console.log(count);
myLists.each(function(element, index) {
element.getText().then(function (text) {
textList[j++] = text;
console.log(index, text);
});
});
});
you should be able to use the textList array to match things.
expect(textList).toEqual(['Attractions', 'Capacity', 'Conent',
'Media', 'Options', 'Upload CADs'
]);

How to attach function to second element of ng-repeat

I just started learning angular
and I have a question related to ng-repeater
I have an ng-repeater like:
<div ng-if="!promo.promotion.useHTML"
class="{{promo.promotion.monetateId}}"
ng-repeat="promo in promotions track by promo.promotion.slotId">
<div ng-if="!promo.useHTML">
<img ng-src="{{promo.promotion.imageURL}}"
ng-click="promoOnClick(promo.promotion.promotionURL)"/>
</div>
I want to have a different ng-click function on second element of repeater.
How would I get this?
You can try using $index variable which contains the repeater array offset index. You can use it to build conditional statements in your repeater.
<div ng-if="!promo.promotion.useHTML" class="{{promo.promotion.monetateId}}" ng-repeat="promo in promotions track by promo.promotion.slotId">
<div ng-if="!promo.useHTML && $index !== 2">
<img ng-src="{{promo.promotion.imageURL}}" ng-click="promoOnClick(promo.promotion.promotionURL)"/>
</div>
<div ng-if="!promo.useHTML && $index == 2">
<img ng-src="{{promo.promotion.imageURL}}" ng-click="promoOnClickAnotherFunction(promo.promotion.promotionURL)"/>
</div>
</div>
Or as suggested by comment below
<div ng-if="!promo.promotion.useHTML" class="{{promo.promotion.monetateId}}" ng-repeat="promo in promotions track by promo.promotion.slotId">
<div ng-if="!promo.useHTML>
<img ng-src="{{promo.promotion.imageURL}}" ng-click="($index==1) ? function1() : function2()"/>
</div>
</div>
or as a third option, you can pass the index into the callback function as a second parameter and move your logic into your controller.
and in your callback, check the index and ... based on the index call your
function1, or function 2. Its a good idea to move logic away from your templates/views.
even better option would be creating/setting your promote() function function in your controller. E.g when you load your promotions array/objects, loop over them and set their promote function based on ... whatever your requirements are.
var i;
var yourPromoteFunctionForSecondElement = function( promo_object ) {
/*do your promo specific stuff here*/
}
for (i = 0; i < promotions.length; i++) {
var promotion = promotions[i];
if ( i == 1 ) {promotion.promote = yourPromoteFunctionForSecondElement(promotion);}
else if () {promotion.promote = someOtherPromoteFunction(promotion);}
else {/*etc*/}
}

Combine divs within a for loop

Is it possible to use a JavaScript for loop to combine a number of div's? I have 16 sets of these I am wanting to put into a for loop. The problem I am having is that its HTML not JavaScript I am trying to do this with. I haven't seen anything so far on how to go about this. Thanks for any help or suggestions.
What the following code does is catch the data pre-defined from a 16X17 table and inserts it into one cell in my document. I then have have other code using the div id's that makes visible just the one I need.
<div id="101" class="hidden"><script>document.write(tab1a1)</script></div>
<div id="102" class="hidden"><script>document.write(tab1a2)</script></div>
<div id="103" class="hidden"><script>document.write(tab1a3)</script></div>
<div id="104" class="hidden"><script>document.write(tab1a4)</script></div>
<div id="105" class="hidden"><script>document.write(tab1a5)</script></div>
<div id="106" class="hidden"><script>document.write(tab1a6)</script></div>
<div id="107" class="hidden"><script>document.write(tab1a7)</script></div>
<div id="108" class="hidden"><script>document.write(tab1a8)</script></div>
<div id="109" class="hidden"><script>document.write(tab1a9)</script></div>
<div id="110" class="hidden"><script>document.write(tab1a10)</script></div>
<div id="111" class="hidden"><script>document.write(tab1a11)</script></div>
<div id="112" class="hidden"><script>document.write(tab1a12)</script></div>
<div id="113" class="hidden"><script>document.write(tab1a13)</script></div>
<div id="114" class="hidden"><script>document.write(tab1a14)</script></div>
<div id="115" class="hidden"><script>document.write(tab1a15)</script></div>
<div id="116" class="hidden"><script>document.write(tab1a16)</script></div>
<div id="117" class="hidden"><script>document.write(tab1a17)</script></div>
Update: Pulling data from table
<!--Start- Takes Assembly number from Data Table--> <!--Change "<Col1;" equala columns-->
for (var x = 1; x<Col1; x++){window["aa"+x] = document.getElementById("part1Table").rows[0].cells[x+1].innerHTML;}
<!--End--- Takes Assembly number from Data Table-->
<!--Start- Takes Assembly Rows from Data Table--> <!--Change "<Row1;" equals rows-->
for (var y = 1; y<Row1+1; y++){window["rows"+y] = document.getElementById("part1Table").rows[y].cells[1].innerHTML;}
<!--End- Takes Assembly Rows from Data Table-->
<!--Start- Takes Part number from Data Table--> <!-- "<Col1;" equals columns----> <!-- If a Column is added to main table add a new line below---->
for (var z1 = 1; z1 <Col1; z1++) {window["tab1a"+z1] = document.getElementById("part1Table").rows[1].cells[z1 +1].innerHTML;}
for (var z2 = 1; z2 <Col1; z2++) {window["tab2a"+z2] = document.getElementById("part1Table").rows[2].cells[z2 +1].innerHTML;}
for (var z3 = 1; z3 <Col1; z3++) {window["tab3a"+z3] = document.getElementById("part1Table").rows[3].cells[z3 +1].innerHTML;}
Try using AngularJS (which is a javascript framework that you can easily add to your html page (see AngularJS.com for a quick intro))
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</head>
<body ng-app='myApp'>
<div ng-repeat='entry in entries'>
<div id={{entry.id}} class="hidden"><script>document.write({{entry.table}})</script></div>
</div>
<script src='app.js'></script>
</body>
</html>
Then within a controller in a file called app.js you would make a array of objects 1...100 or whatever number you want and pass it to a scope like this
var myApp = angular.module('myApp', []);
myApp.controller('MainCtrl', function($scope) {
$scope.entries = [{
id: '101', table: 'tab1a1'}, {id: '102', table: 'tab1a2'}]
// extend to your own range
});
having a bunch of sequential variables like tab1a1 is difficult to work with. Can you put those in an array? Then...
var b=document.getElementsByTagName('body')[0];
for(var i=1; i<18; i++){
var d=document.createElement('div'); //make a div element
d.id='10'+i; //assign sequential id
d.innerHTML=tab1a[i]; //put the the array element content corresponding to that number into the new div element
b.appendChild(d); //place new element into the DOM
}
Another option would be to use excel and basically make a column with on the rows 101,102,103... And a similar same column for the tables. Then just add the code lines in string format and bind the colums together with &. Copy everything and paste this in notepad and then in your code!
Ex:
="<div id='" & A1 & "' etc etc
Thank you to everyone who gave suggestions. I spent a few more hours with the code and came up with the following. It works great in testing. I can now add and remove rows and columns from my table without having to change the code.
for (var w = 1; w <Row1; w++)
for (var z1 = 1; z1 <Col1; z1++) {window["tab" + w + "a" + z1] = document.getElementById("part1Table").rows[w].cells[z1 +1].innerHTML;}
This replaces my 17 lines of the following:
for (var z17 = 1; z17 <Col1; z17++) {window["tab17a"+z17] = document.getElementById("part1Table").rows[17].cells[z17 +1].innerHTML;}
This is very good because my new table has 50+ rows.

How to add Contact List data into PhoneGap ListView

I have a javascript function which will read the device ContactList and add them into a javascript array.In my HTML page i have taken a listview.Now as per my requirement i have to add these array data into the listview by jquery dynamically which i am not able to do .I am not able to see anything on the screen of the mobile on launching the app..
Here is my javascript code to read from Mobile's contact list..
function onDeviceReady() {
// specify contact search criteria
var options = new ContactFindOptions();
options.filter=""; // empty search string returns all contacts
options.multiple=true; // return multiple results
filter = ["displayName"]; // return contact.displayName field
// find contacts
navigator.contacts.find(filter, onSuccess, onError, options);
}
var names = [];
// onSuccess: Get a snapshot of the current contacts
//
function onSuccess(contacts) {
for (var i=0; i<contacts.length; i++) {
if (contacts[i].displayName) { // many contacts don't have displayName
names.push(contacts[i].displayName);
}
}
alert('contacts loaded');
}
and here is my HTML listview..
<div data-role="page" id="home" data-theme="c">
<div data-role="content">
<div id="header" class="header">
<h1>Contact Directory</h1>
</div>
<ul data-role="listview" id="contactlist" data-theme="a">
</ul>
</div>
</div>
So, My question is how can i add the array values into the listview by jquery dynamically..
Thanks..
Couple of ways, but here is one way.
Create a simple string variable to hold your LIs.
Loop over names and append to the string <li> + names[x] + </li> where X is your loop counter.
Use jQuery to get the UL dom and then do .html(s) where s is your string.
Basically you are injecting <li>...</li><li>...</li> into your UL.
The last step is to refresh the list view so jQuery displays it correctly. This is done with the refresh API, defined here: http://api.jquerymobile.com/listview/#method-refresh

sorting elements using jquery

I have a div, #containerDiv, which contains elements related to users like first name, last name etc. in separate divs. I need to sort the contents of the container div based on the last name, first name etc. values.
On searching google the examples I got all are appending the sorted results and not changing the entire HTML being displayed. They are also not sorting by specific fields (first name, last name).
So please help me in sorting the entire content of #containerDiv based on specific fields and also displaying it.
The Page looks Like something as mentioned Below:
<div id="containerDiv">
<div id="lName_1">dsaf</div><div id="fName_1">grad</div>
<div id="lName_2">sdaf</div><div id="fName_2">radg</div>
<div id="lName_3">asdf</div><div id="fName_3">drag</div>
<div id="lName_4">fasd</div><div id="fName_4">gard</div>
<div id="lName_5">dasf</div><div id="fName_5">grda</div>
<div id="lName_6">asfd</div><div id="fName_6">drga</div>
</div>
On getting sorted by last name div values, the resulted structure of the container div should look like:
<div id="containerDiv">
<div id="lName_3">asdf</div><div id="fName_3">drag</div>
<div id="lName_6">asfd</div><div id="fName_6">drga</div>
<div id="lName_5">dasf</div><div id="fName_5">grda</div>
<div id="lName_1">dsaf</div><div id="fName_1">grad</div>
<div id="lName_4">fasd</div><div id="fName_4">gard</div>
<div id="lName_2">sdaf</div><div id="fName_2">radg</div>
</div>
Now I think you all can help me in a better way.
this is a sample example:
html:
<div id="containerDiv">
<div>2</div>
<div>3</div>
<div>1</div>
</div>
js
$(function() {
var container, divs;
divs = $("#containerDiv>div").clone();
container = $("#containerDiv");
divs.sort(function(divX, divY) {
return divX.innerHTML > divY.innerHTML;
});
container.empty();
divs.appendTo(container);
});
you may set your divs.sort function param depend on your goal.
jsFiddle.
and a jQuery Plugin is suitable
I suggest you read the div values so you get an array of objects (persons for example) or just names and perform a sort operation on that. Than...output the result to the initial div (overwriting the default values).
I have built a jQuery sort function in which you can affect the sort field.
(it rebuilds the html by moving the row to another location).
function sortTableJquery()
{
var tbl =$("#tbl tr");
var store = [];
var sortElementIndex = parseFloat($.data(document.body, "sortElement"));
for (var i = 0, len = $(tbl).length; i < len; i++)
{
var rowDom = $(tbl).eq(i);
var rowData = $.trim($("td",$(rowDom)).eq(sortElementIndex).text());
store.push([rowData, rowDom]);
}
store.sort(function (x, y)
{
if (x[0].toLowerCase() == y[0].toLowerCase()) return 0;
if (x[0].toLowerCase() < y[0].toLowerCase()) return -1 * parseFloat($.data(document.body, "sortDir"));
else return 1 * parseFloat($.data(document.body, "sortDir"));
});
for (var i = 0, len = store.length; i < len; i++)
{
$("#tbl").append(store[i][1]);
}
store = null;
}
Every time I need to sort lists I use ListJs.
It's well documented, has good performance even for large lists and it's very lightweight (7KB, despite being library agnostic).

Categories

Resources