Parsing JSON data using JavaScript push - want to prevent automatically closing divs - javascript

I'm working on parsing JSON data and converting it to html form.
I'm using the javascript push function, which I thought would push the data into the array I've designated it to in the order I push it. However, whenever I push a new div element, it is automatically closed after being pushed making the html come out in a different order I want. Is there a way I can prevent this?
JavaScript:
$(function(){
var container = $('.panel-body');
var jsonObj = $.parseJSON('{"fields":[{"label":"Nafn form / Form name","field_type":"sFormName","required":false,"field_options":{"size":"small"},"cid":"c2"},{"label":"Spurning 1 ","field_type":"QuestionText","required":false,"field_options":{"size":"small"},"cid":"c5"},{"label":"Spurning 2","field_type":"QuestionCheckbox","required":false,"field_options":{"options":[{"label":"","checked":false},{"label":"","checked":false}]},"cid":"c9"},{"label":"Spunring 4","field_type":"QuestionRadio","required":false,"field_options":{"options":[{"label":"Val","checked":false},{"label":"VAl ","checked":false},{"label":"Val","checked":false}],"include_other_option":false},"cid":"c13"},{"label":"Spurning með multi","field_type":"QuestionMultiBegin","required":false,"field_options":{"options":[{"label":"","checked":false},{"label":"","checked":false}]},"cid":"c17"},{"label":"Spurning","field_type":"QuestionDropdown","required":false,"field_options":{"options":[{"label":"Val","checked":false},{"label":"Val","checked":false},{"label":"Val","checked":false}],"include_blank_option":false},"cid":"c21"},{"label":"Skráning","field_type":"Registration","required":false,"field_options":{"options":[{"label":"Notendanafn / Username"},{"label":"Lykilorð / Password"}],"include_blank_option":false},"cid":"c25"}]}');
var body = [];
var headerData = jsonObj.fields;
console.log(headerData);
for (var i = 0; i < headerData.length; i++) {
if(jsonObj.fields[i].field_type == "sFormName") {
body.unshift("<div class='panel panel-default panel-element'><div class='panel-heading'>" + jsonObj.fields[i].label)
} else {
body.push("<div class='panel panel-default panel-element'><div class='panel-heading'>" + jsonObj.fields[i].label);
}
if (jsonObj.fields[i].field_type == "QuestionText") {
body.push("<div class='panel-body'><textarea class='large-text form-control'></textarea></div>");
} else if (jsonObj.fields[i].field_type == "QuestionParagraph") {
body.push(jsonObj.fields[i].field_options.description);
} else if (jsonObj.fields[i].field_type == "QuestionDropdown") {
var data = jsonObj.fields[i].field_options.options;
body.push("<div class='panel-body'><div class='dropdown'><button class='btn btn-default dropdown-toggle' type='button' data-toggle='dropdown' id='dropdownMenu1' aria-haspopup='true' aria-expanded='true'>" + jsonObj.fields[i].field_options.options[0].label + "<span class='caret'></span></button>");
body.push("<ul class='dropdown-menu' aria-labelledby=dropdownMenu1'>");
for(var j = 0; j < data.length; j++) {
body.push("<li><a href='#'>" + jsonObj.fields[i].field_options.options[j].label + "</a></li>");
}
body.push("</ul></div></div>");
} else if (jsonObj.fields[i].field_type == "QuestionRadio") {
var data = jsonObj.fields[i].field_options.options;
body.push("<div class='panel-body'>");
for(var j = 0; j < data.length; j++) {
body.push("<div class='radio'><div class='controls'><input type='radio' name='radio'></input>" + jsonObj.fields[i].field_options.options[j].label);
}
body.push("</div></div></div></div>");
} else if (jsonObj.fields[i].field_type == "Registration") {
body.push("<div class='panel-body'>");
body.push("<div class='form-group'><form class='reg-form' role='form'><div class='form-group'><label for='email'>" + jsonObj.fields[i].field_options.options[0].label + "</label>");
body.push("<input type'email' class='form-control' id='email'></div>");
body.push("<div class='form-group'><form class='reg-form' role='form'><div class='form-group'><label for='pwd'>" + jsonObj.fields[i].field_options.options[1].label + "</label>");
body.push("<input type'password' class='form-control' id='pwd'></div>");
body.push("<div class='checkbox'><label><input type='checkbox'> Muna mig / Remember me</label></div></form></div>");
}
$(container).html(body);
}});
As you can see, I wrote the code assuming that I would have to push an ending div to each element that I'd opened, however that seems to be ignored.

The problem here is that you're trying to pass the body array to the html method, however you should instead concatenate all strings inside of it, the pass it.
Like so:
var htmlMarkup = body.reduce(function(){
return prev + current;
}, '');
or use 'join' as suggested by Hacketo, since it's less verbose:
var htmlMarkup = body.join('');
$(container).html(htmlMarkup);

Related

How to sort AJAX results using toggle button

I have made an AJAX request that fetches completed Ebay auction results using Ebay's API (Finding Service). It works, producing the desired results, but now I am a stuck on how best to filter those results (in my case, using a button) by price, date of sale, etc.
For example: I have the variable url which has the filter url += "&sortOrder=StartTimeNewest";. I would like a button to toggle between that filter and url += "&sortOrder=StartTimeOldest"; using a click event.
I am a student, and pretty inexperienced when it comes to JS/frameworks...and so far have not had much luck figuring out the best way to do this aside from duplicating my entire code from ebay.js and altering it slightly for each filter I would like to apply.
For example: I can create different variables like url1, url2 and so on that have the filters I want, calling them from a different ajax requests attached to the buttons...
...but I'm sure there is a better and simpler way to do this without being so repetitive and would appreciate any help pointing me in the right direction.
Ebay.js
$(window).load(function() {
$('form[role="search"]').submit(function(ev) {
ev.preventDefault();
var searchstring = $('input[type="text"]', this).val();
var url = "https://svcs.ebay.com/services/search/FindingService/v1";
url += "?OPERATION-NAME=findCompletedItems";
url += "&SERVICE-VERSION=1.13.0";
url += "&SERVICE-NAME=FindingService";
url += "&SECURITY-APPNAME=BrandonE-DigIt-PRD-5cd429718-3d6a116b";
url += "&GLOBAL-ID=EBAY-US";
url += "&RESPONSE-DATA-FORMAT=JSON";
url += "&REST-PAYLOAD";
url += "&itemFilter(0).name=MinPrice";
url += "&itemFilter(0).value=7.00";
url += "&itemFilter(0).paramName=Currency";
url += "&itemFilter(0).paramValue=USD";
url += "&paginationInput.pageNumber=1";
url += "&paginationInput.entriesPerPage=50";
url += "&keywords=" + searchstring;
url += "&sortOrder=StartTimeNewest";
url += "&categoryId=176985";
$.ajax({
type: "GET",
url: url,
dataType: "jsonp",
success: function(res){
console.log(res);
var items = res.findCompletedItemsResponse[0].searchResult[0].item;
var ins = "";
for (var i = 0; i < items.length; i++){
ins += "<div>";
ins += "<img src='" + items[i].galleryURL + " '/>";
ins += " " + items[i].title + " - ";
ins += "Sold for $" + items[i].sellingStatus[0].currentPrice[0].__value__;
ins += "</div><br />";
};
$('.results').html(ins);
}
});
});
});
HTML:
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button id="mainbtn" type="submit" class="btn btn-default">Search</button>
</form>
<div class="filters col-xs-12 col-md-10 col-offset-md-1">
<!-- TOGGLE BUTTONS WILL ALLOW RESULTS TO BE SORTED. -->
<button type="button" class="btn btn-info btn-sm date-btn">date</button>
<button type="button" class="btn btn-info btn-sm price-btn">price</button>
</div>
<br />
<div class="index col-xs-12 col-md-10 col-offset-md-1">
<p class="restitle">results:</p><br />
<div class="results"></div>
</div>
Per our comments, I created a simple class that will generate the url for you.
Go ahead and tweek it to get the correct values in there. Hopefully this helps!
I added comments in the code but lmk if you have any questions.
$(function() {
// invoke click event
$("[data-filter]").off();
$("[data-filter]").on("click", function() {
let $this = $(this);
let data = $this.data();
// toggle value
if (data.value == false) {
$(this).data("value", true);
} else {
$(this).data("value", false);
}
// create class
let url = new buildfindCompletedItemsUrl();
// get the sort order
url.getSortOrder();
// build the url
let ajaxUrl = url.build();
// get the results
GetFilteredResults(ajaxUrl, function(results) {
$("body").append($("<p />", {
text: results
}));
})
});
})
// class with contructor
function buildfindCompletedItemsUrl() {
this.url = "https://svcs.ebay.com/services/search/FindingService/v1";
this.defaultUrlParams = {
"OPERATION-NAME": "findCompletedItems",
"SERVICE-VERSION": "1.13.0",
"SERVICE-NAME": "FindingService",
"SECURITY-APPNAME": "BrandonE-DigIt-PRD-5cd429718-3d6a116b",
"GLOBAL-ID": "EBAY-US",
"RESPONSE-DATA-FORMAT": "JSON",
"REST-PAYLOAD": "",
"itemFilter(0).name": "MinPrice",
"itemFilter(0).value": "7.00",
"itemFilter(0).paramName": "Currency",
"itemFilter(0).paramValue": "USD",
"paginationInput.pageNumber": "1",
"sortOrder": "",
"paginationInput.entriesPerPage": "50",
"categoryId": "176985"
}
return this;
}
// looks at the dom and fills the sortOrderParam
buildfindCompletedItemsUrl.prototype.getSortOrder = function() {
var $filters = $("[data-filter]");
let param = this.defaultUrlParams["sortOrder"];
let _ = this;
$.each($filters, function(i, f) {
let $filter = $(f);
let data = $filter.data();
let val = data.value;
if (val == true) {
if (_.defaultUrlParams["sortOrder"] == "") {
_.defaultUrlParams["sortOrder"] += data.filter;
} else {
_.defaultUrlParams["sortOrder"] += "," + data.filter;
}
}
})
};
// builds the full url for the ajax call
buildfindCompletedItemsUrl.prototype.build = function() {
let _url = this.url;
let keys = Object.keys(this.defaultUrlParams);
let length = keys.length;
for (let i = 0; i < length; i++) {
let key = keys[i];
let val = this.defaultUrlParams[key];
if (i == 0) {
_url += `?${key}=${val}`;
} else {
_url += `&${key}=${val}`;
}
}
return _url;
}
// get your results and return them
function GetFilteredResults(url, callback) {
// do ajax here
return callback(url)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-filter="date" data-value="false">Sort By Date</button>
<button data-filter="price" data-value="false">Sort By Price</button>

JavaScript function to generate dropdowns / remove dropdown menus

I am trying to add and remove dropdown <select>s to a form on a button click. This is the code I have currently. I could have sworn I had this working last night, but when I went to work some more on my project this morning, the dropdowns wouldn't add / remove correctly.
function DropDowns(){
this.counter = 0;
this.addDropdown = function (divname) {
var newDiv = document.createElement('div');
var html = '<select name="cookie' + this.counter + '">', i;
for (i = 0; i < cookies_drop.length; i++) {
html += "<option value='" + cookies_drop[i] + "'>" + cookies_drop[i] + "</option>"
}
html += '</select>';
newDiv.innerHTML = html;
document.getElementById(divname).appendChild(newDiv);
this.counter++;
}
this.remDropdown = function() {
$('#dropdowns-container').find('div:last').remove();
this.counter--;
}
}
var dropsTest = new DropDowns();
HTML:
<form action='' method=post id="dropdowns-container">
<button id="add_cookie" type="button" onclick="dropsTest.addDropdown('dropdowns-container');">add cookie</button>
<button id="rem_cookie" type="button" onclick="dropsTest.remDropdown();">remove cookie</button>
<input name="cookies" type=submit value="submit">
</form>
I can only figure out the main problem may be on the server side when you create the cookies_drop variable using json_encode.
Other problems may reside in:
A test on the parameter of addDropdown function is suggested to check if it's valid
In the function remDropdown the decrement of the counter variable must be done only if the element is actually removed
You mixed jQuery and javaScript
Instead of using directly the createElement, making the code more simple and readable, you used the innerHTML property.
So, my snippet is:
// I assume you used something like:
// var cookies_drop = JSON.parse( '<?php echo json_encode($data) ?>' );
var cookies_drop = [{text: "Text1", val: "Value1"},
{text: "Text2", val: "Value2"},
{text: "Text3", val: "Value3"}];
function DropDowns() {
this.counter = 0;
this.addDropdown = function (divname) {
var divEle = document.querySelectorAll('form[id=' + divname + ']');
if (divEle.length != 1) {
return; // error
}
var newDiv = document.createElement('div');
var newSelect = document.createElement('select');
newSelect.name = 'cookie' + this.counter;
newDiv.appendChild(newSelect);
for (var i = 0; i < cookies_drop.length; i++) {
var newOption = document.createElement('option');
newOption.value = cookies_drop[i].val;
newOption.text = cookies_drop[i].text;
newSelect.appendChild(newOption);
}
divEle[0].appendChild(newDiv);
this.counter++;
}
this.remDropdown = function () {
var lastDiv = document.querySelectorAll('#dropdowns-container div:last-child');
if (lastDiv.length == 1) {
lastDiv[0].parentNode.removeChild(lastDiv[0]);
this.counter--;
}
}
}
var dropsTest = new DropDowns();
<form action="" method="post" id="dropdowns-container">
<button id="add_cookie" type="button" onclick="dropsTest.addDropdown('dropdowns-container');">add cookie</button>
<button id="rem_cookie" type="button" onclick="dropsTest.remDropdown();">remove cookie</button>
<input name="cookies" type=submit value="submit">
</form>

Loop through unknown amount of spans - JavaScript MVC

I have these functions:
$(".Read-Showing-Comment-Cancel").live('click', function (e) {
var guid = $(this).data("guid");
e.preventDefault();
var f = $('#comments-form-' + guid).slideUp();
$('comments-text-' + guid).empty();
$('comments-text-' + guid).value = "";
$(this).find('.comments-form-' + guid).hide();
$('comments-sendlink-' + guid).show();
});
$('.showComments').unbind('click').click(function (event) {
$('.ListingDisplayOptions').hide();
$(this).find('.comments-form-' + showGuid).show();
var showGuid = $(this).attr('rel');
loadShowingsComments(showGuid);
$(this).attr('id', 'comments-sendlink-' + showGuid);
event.preventDefault();
});
function loadShowingsComments(guid) {
var commentTextArea = "#comments-form-" + guid;
var commentDisplay = ".spanComments" + guid;
var curComment = $(commentDisplay).text();
var element = "#comments-form-" + guid;
$(element).slideDown();
}
<script>
function showComments() {
var comments = document.querySelectorAll(".spanComments");
for (var i = 0; i < comments.length; i++) {
comments[i].innerHTML = "This is comment #" + i;
}
}
</script>
View Comments
Those functions should grab the information from my controller (it's hooked up correctly. I've stepped through that and it has populated the right information) and place them in my span:
<tr class="p_la" id="comments-form-#currentShowing.ShowingGUID" style="display:none;">
<td colspan="4" style="border-right:5px solid #DDDDDD;">
<form action="" method="post">
<span class="spanComments" cols="100" rows="5">#string.Format("{0} / {1}", #currentShowing.Comments.DateAdded, #currentShowing.Comments.CommentsValue)</span>
<br />
Close
</form>
</td>
</tr>
Unfortunately, when I click on my hyperlink, it only populates the first span with the first span's information. Works great for the first span but when you click on the hyperlink in the second, third, fourth, etc item, they will only open up the first span with the first span's information.
The code should populate each successive span with its own information.
My JQuery was off. It needed this to be changed:
$(".Read-Showing-Comment-Cancel").live('click', function (e) {
var guid = $(this).data("guid");
e.preventDefault();
var f = $('#comments-form-' + guid).slideUp();
$('comments-text-' + guid).empty();
$('comments-text-' + guid).value = "";
$(this).parent("form").parent("td").parent("tr").hide();
$('comments-sendlink-' + guid).show();
});
$('.showComments').unbind('click').click(function (event) {
$('.ListingDisplayOptions').hide();
var showGuid = $(this).attr('rel');
$(this).parent("td").parent("tr").next('#comments-form-' + showGuid).show();
$(this).attr('id', 'comments-sendlink-' + showGuid);
event.preventDefault();
});

Retrieving Input Values from a Text Box

I need to make a box so that when the user enters a value of one through 6, it rolls that many dice. I'm a complete beginner to javascript and any help would be greatly appreciated.
Here's my function:
function NumberValue() {
for (i = 0; i <['randNumber']; i++){
var numberRoll = Math.floor(Math.random() * 6) + 1;
var userNumber = '../images/die' + numberRoll + '.gif';
myNewTag = "<img id='dieImgRandom' src='" + userNumber + "'>"
document.getElementById('dieDivRandom').innerHTML += myNewTag;
And here is my body element:
<h1>Why don't you pick please?</h1>
<div id="dieDivRandom" style="text-align:center">
<p>
<div id="dieImageRand">
<img id="dieImgRandom" alt="die image" src="../images/die1.gif">
<br>
<input type="text" id="randNumber" size=20 value="Enter 1 through 6">
<input type="button" value="Click to Roll" onclick="NumberValue();">
</div>
The function needs to allow a user to submit the number one, two, three, four, five, or six, and that many images need to display on the screen. The images a relocated in my images folder, so relative links will work just fine. That's actually what I need to use. Thank you.
Replace:
for (i = 0; i <['randNumber']; i++){
With:
for (i = 0; i <document.getElementById('randNumber').value; i++) {
The <input /> tag can be accessed by using either of the following:
document.getElementById('inputId').value;
document.formName.inputName.value
Finally, your code becomes:
function NumberValue() {
for (i = 0; i < document.getElementById('inputId').value; i++) {
var numberRoll = Math.floor(Math.random() * 6) + 1;
var userNumber = '../images/die' + numberRoll + '.gif';
myNewTag = "<img id='dieImgRandom' src='" + userNumber + "'>"
document.getElementById('dieDivRandom').innerHTML += myNewTag;
}
}
Use this to read values from textbox
function NumberValue() {
var ranNum = document.getElementById('randNumber').value;
for (i = 0; i <ranNum ; i++){
}
}
EDIT:
If you want to validate the Entered number
add this block of code
function NumberValue() {
var ranNum = document.getElementById('randNumber').value;
if(ranNum < 1 || ranNum > 6) {
alert("Please enter number from 1 to 6 only");
return false;
}
for (i = 0; i <ranNum ; i++){
}
return true;
}

Display Contacts in Phonegap

when i have to open this page i want to display all contacts in phone with out click on any button.
Here myFunction() displays all contacts.
I have to call `myFunction()`, in this code. I dont know where to call this function. Help me
var ar1 = new Array;
var ar2 = new Array;
var name, number;
var counter = 1;
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
var options = new ContactFindOptions();
options.filter = "";
options.multiple = true;
filter = [ "displayName", "phoneNumbers" ];
navigator.contacts.find(filter, onSuccess, onError, options);
}
function onSuccess(contacts) {
for ( var i = 0; i < contacts.length; i++) {
for ( var j = 0; j < contacts[i].phoneNumbers.length; j++) {
name = contacts[i].displayName;
number = contacts[i].phoneNumbers[j].value;
ar1.push(name);
ar2.push(number);
// here i called myFunction(), but it's displaying one contact in multiple times
}
// here i called myFunction(), but it's displaying one contact in multiple times
}
// Here i called myFunction(), the function is not calling
}
function onError(contactError) {
alert('onError!');
}
// where to call this function
function myFunction() {
$("#checkall").click(function() {
if ($(this).is(':checked')) {
$(":checkbox").attr("checked", true);
} else {
$(":checkbox").attr("checked", false);
}
});
for ( var i = 0; i < ar2.length; i++) {
var newTextBoxDiv = $(document.createElement('div')).attr("id",
'TextBoxDiv' + counter);
newTextBoxDiv.after().html(
'<input type="checkbox" value="'
+ ar1[i] + '"/>'
+ ar1[i] + " " + " " + ar2[i] + '</br>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
}
}
</script>
</head>
<body>
</br>
<div id="TextBoxesGroup">
<div id="TextBoxDiv1">
<input type="checkbox" id="checkall" value="check" />selectAll</br> <br />
<br /> <br />
</div>
</div>
</body>
</html>
I cannot catch what you want exactly.
if you want to generating phonenumber checkbox list when your app starts,
just call myFunction() in end of onSuccess() callback.
if you want another time, you should define a event handler that you want like below.
$("#PhonenumberListButton" ).click( function() { myFunction(); } );
and your code can occur index exception during loop.
Let's think about below.
each contact has 1 name but has 1 or more phone numbers
your code pushes each name into ar1 and also pushes each phone numbers of contact into ar2
so ar2.length can be greater than ar1.length
your generating display code use ar2.length for loop. it should make exception if any contact has 2 or more phonenumbers.
This's a reason of stop your loop in onSuccess().
Fixed Code
function onSuccess(contacts) {
for ( var i = 0; i < contacts.length; i++) {
name = contacts[i].displayName;
ar1.push(name);
ar2[i] = []; // array for multiple phone#.
for ( var j = 0; j < contacts[i].phoneNumbers.length; j++) {
number = contacts[i].phoneNumbers[j].value;
ar2[i].push(number);
}
}
myFunction(); // display phone numbers
}
function myFunction() {
$("#checkall").click(function() {
if ($(this).is(':checked')) {
$(":checkbox").attr("checked", true);
} else {
$(":checkbox").attr("checked", false);
}
});
for ( var i = 0; i < ar2.length; i++) {
if ( ar2[i].length ) { // avoid none phone# exception
var newTextBoxDiv = $(document.createElement('div')).attr("id",
'TextBoxDiv' + counter);
newTextBoxDiv.after().html(
'<input type="checkbox" value="'
+ ar1[i] + '"/>'
+ ar1[i] + " " + " " + ar2[i][0] + '</br>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
}
}
}

Categories