Variable from attribute only displays the first word - javascript

I have a listview which is dynamically populated with offers for a store locator I am developing. The listview populates perfectly fine with a formatted list with the offer title and offer description.
I am trying to create a saved feature where the user can save offers for offline use. To do this I am transferring the database values into attributes of the dynamic listview where I can place them into variables for use in sessions/localstorage etc.
Here is my js code that defines the attributes and displays the listview.
var output1 = '';
function getoffers(data) {
var data = JSON.parse(data);
console.log(data);
$.each(data, function(index, value){
output1 += '<li offertitle='+value.offer_title+' offer-desc='+value.offer_desc+' offer-expiry='+value.expiry_date+'><h1>'+value.offer_title+'</h1><p>'+value.offer_desc+'</p><p class="ui-li-aside"><b>Expiry Date:</b>'+value.expiry_date+'</p></li>';
});
$('#offerlist').html(output1).listview().listview('refresh');
}
As you can see, I display the database values and assign them to attributes in their dynamic listview row.
I create the variables on click of the listview row where I alert each variable for testing. This is where I discover that the variable only has the first word (of what should be a paragraph).
Eg. An offer that should say "Buy one, get one free". Only returns "Buy" in the variable.
$("#offers ul").on("click", ">li", function(event, ui) {
var offertitle = $(this).closest('li').attr('offertitle');
var offerdesc = $(this).closest('li').attr('offer-desc');
var offerexpiry = $(this).closest('li').attr('offer-expiry');
alert(offertitle);
alert(offerdesc);
alert(offerexpiry);
});

You're not quoting the attribute, so only the first word is treated as part of it.
You need to set it like:
output1 += '<li offertitle="'+value.offer_title+'" offer-desc="'+value.offer_desc+'" offer-expiry="'+value.expiry_date+'"><h1>'+value.offer_title+'</h1><p>'+value.offer_desc+'</p><p class="ui-li-aside"><b>Expiry Date:</b>'+value.expiry_date+'</p></li>';
As an aside, you shouldn't be defining your own custom attributes, but rather using HTML data attributes.

Related

Mapping JSON value in Javascript [duplicate]

I have a listview which is dynamically populated with offers for a store locator I am developing. The listview populates perfectly fine with a formatted list with the offer title and offer description.
I am trying to create a saved feature where the user can save offers for offline use. To do this I am transferring the database values into attributes of the dynamic listview where I can place them into variables for use in sessions/localstorage etc.
Here is my js code that defines the attributes and displays the listview.
var output1 = '';
function getoffers(data) {
var data = JSON.parse(data);
console.log(data);
$.each(data, function(index, value){
output1 += '<li offertitle='+value.offer_title+' offer-desc='+value.offer_desc+' offer-expiry='+value.expiry_date+'><h1>'+value.offer_title+'</h1><p>'+value.offer_desc+'</p><p class="ui-li-aside"><b>Expiry Date:</b>'+value.expiry_date+'</p></li>';
});
$('#offerlist').html(output1).listview().listview('refresh');
}
As you can see, I display the database values and assign them to attributes in their dynamic listview row.
I create the variables on click of the listview row where I alert each variable for testing. This is where I discover that the variable only has the first word (of what should be a paragraph).
Eg. An offer that should say "Buy one, get one free". Only returns "Buy" in the variable.
$("#offers ul").on("click", ">li", function(event, ui) {
var offertitle = $(this).closest('li').attr('offertitle');
var offerdesc = $(this).closest('li').attr('offer-desc');
var offerexpiry = $(this).closest('li').attr('offer-expiry');
alert(offertitle);
alert(offerdesc);
alert(offerexpiry);
});
You're not quoting the attribute, so only the first word is treated as part of it.
You need to set it like:
output1 += '<li offertitle="'+value.offer_title+'" offer-desc="'+value.offer_desc+'" offer-expiry="'+value.expiry_date+'"><h1>'+value.offer_title+'</h1><p>'+value.offer_desc+'</p><p class="ui-li-aside"><b>Expiry Date:</b>'+value.expiry_date+'</p></li>';
As an aside, you shouldn't be defining your own custom attributes, but rather using HTML data attributes.

Standard way of building an arbitrary length table in Javascript

I'm receiving data from a websocket (live stream), and trying to put it into a table. I'm currently using the following code:
var table = document.getElementById("websocket-data");
function writeToScreen(message) {
var new_row = table.insertRow(0);
var cell1 = new_row.insertCell(0);
var cell2 = new_row.insertCell(1);
var obj = JSON.parse(message.data);
console.log(obj.value);
cell1.innerHTML = obj.id;
cell2.innerHTML = obj.value;
}
This works, and creates a new row for every JSON packet. The functionality that I am looking for is: On receipt of a JSON, if the id is not in the table, then create a row with id and value, however, if the id is already in the table, simply update the value. I've come across a few ways of doing this, but I'd like to know what the 'proper' way to do it is. I was thinking that perhaps the data should go into an array, and then the array should populate the table, but that would involve repopulating the entire table every time the array changed... I'm happy to use JQuery or similar if necessary.
You could use an array and repopulate the table every time like you said, and if the table will only ever be small then you may not run into issues with that.
One possible alternative of many is maintaining an object in the background with your ids as keys and then store the value and the table row index as values.
Something like:
var tableStore = {};
function recieveMessage(message) {
var obj = JSON.parse(message);
// if the id is not in the tableStore, add it!
if (tableStore[obj.id] === undefined) {
// insert new row into table and save the index into `newTableRowIndex`
// store a blank value (updated below) and the index in the table where it will be displayed
tableStore[obj.id] = {value: undefined, tableIndex: newTableRowIndex};
}
// if the value recieved is different than the stored value, update the row
if (obj.value !== tableStore[obj.id].value) {
tableStore[obj.id].value = obj.value; // store the new value
var row = getTableRow(tableStore[obj.id].tableIndex); // your own function to get the row based on index
// update the row to display the new information
}
}
This could be improved and made to be more organized but you should get the idea.
This way it would only update anything in the display if the new information recieved is different than the old information already stored.
This way should also perform better than using an array would if the table has the potential to get very large as you would not need to search through the entire array every time to see if the id is already stored or not. You would simply access the tableStore entry directly using the id.

Get selected data array from kendo multiselect

I am trying to get an array of the selected items from my Kendo multiselect, which is in the editor template of a kendo grid.
The multiselect code:
#(Html.Kendo().MultiSelect()
.Name("Staff")
.DataValueField("ID")
.DataTextField("FullName")
.BindTo((System.Collections.IEnumerable)ViewData["Staff"])
.Events(events => events
.Change("onChange")
)
.HtmlAttributes(new { #class = "col-md-7 details-editor" })
)
I want to extract the selected items using JQuery - specifically, I want the DataValueField, which is an integer. I have tried several things, but have been unable to get the appropriate integers, rather than the index of the item in the ViewData collection. Some of the approaches I have tried.
var data = $("#Staff").data("kendoMultiSelect").dataItems();
var data = $("#Staff").data("kendoMultiSelect").value();
I don't really know what to do from here, how to use one of the above or a different route to obtain the correct int array.
Thanks for any help!
The answer is simpler than you would think.
$('#Staff').val();
That will return a comma delimited list of whatever is in your .DataValueField. In your case, a comma delimted list of 'ID'.
To get the IDs of the selected items, you can write your onChange method as follows:
var onChange = function(e) {
var arrayOfNames = this.value();
// Do other stuff here...
};
Documentation for the change event which gets fired can be found here.
I've also written a working example here.
Add a .Select("onSelect") event to the Multiselect and append the Value to hidden element every time when user selects the items using:
function onSelect(e) {
var item = e.item;
var text = item.text();
var $data = $('#myHidden');
$data.val($data.val() + text);
};

jQuery using cloned data to filter table

I am having some issues that I can't seem to track down.
Order of Operations:
PHP Renders Table to the page
jQuery Clones the table and stores it as a global variable
When a user clicks on the filter button, it appends the global variable to the DOM and removes rows that don't meet the filter criteria.
Somehow, this is impacting the global variable as when I go through the different filters, it eventually no longer appends data as if its removing the rows from the global variable I keep appending and manipulating.
My Table has rows like so:
<tr data-area-count="2" data-region-count="2" data-regions="North America, EMEA" data-areas="Area 1, Area 2">
My jQuery:
// Global Vars
var results,
oTable;
$(function() {
results = $('[name=resultsTable]').clone();
});
There are several buttons on the page a user can filter the data by. When they click on the button, this is the function that is run:
// Depending on which region needs to be shown, toggle here.
function filterRegion(region) {
var data = results,
tempArray = Array(),
tempAreas,
tempRegions;
// Based on the region/option we selected..
switch (region) {
case 'EMEA':
// Append the data to the dom
$('.res').empty().append(data).find('table').addClass('dt');
// Loop over the rows
$('.res').find('.results tr').each(function() {
// Collect the values of each of the rows we interate over
tempRegions = $(this).data('regions');
tempArray = tempRegions.split(", ");
tempRow = $(this);
// Check to see if this case value exists in the array
if (jQuery.inArray('EMEA', tempArray) == -1) {
// the region is not in the array, remove the row
tempRow.remove();
};
});
break;
}
In the statement above, I expect it to append he original, untouched, version of the table that was initially loaded and then if EMEA was not in the list of data-regions, it would remove all of the rows from the table in the DOM.
However, it seems to be altering data in the global variable because when I toggle back between the different filters, I am eventually left with no data being appended to the DOM since its "removed" all the rows when hitting each of the filter statements.
I feel that I am cloning or using the cloned data incorrectly. Any thoughts?
From the json append documentation (https://api.jquery.com/append/):
If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved into the target (not cloned).
So I think in your append(data) call you move the data from your global result variable there. Then later you remove elements from it (which modifies the global results DOM object). Instead you have to clone it once again. So I think replacing the line
var data = results,
with
var data = results.clone(),
should solve the problem. I didn't test it though.

Change the div's in another html page

still learning some javascript here, got done other things but now the final and most important part of it.
I have two html pages - one of which uses javascript to dynamically add text-fields (and to remove them of course) (genmain.html) and the other one where the text field input should go(table.html).
So i have already created a function to retrieve the array of values.
function getElementArray(divName){
var names = document.getElementsByName("namefield");
}
The variable names is an array and it has all the values from fields.
The problem is I would like to set these values from array to the values of another div on the page. After some searching i understood that it could be done with 'id'-s but i'm not that sure and don't completely understand how.
Let's say i have a lot of div's on another page (table.html) but some of them have id="MAIN". I would like to change the value inside of the div
For example
<div id="MAIN">THIS PART I WANT TO CHANGE</div>
Javascript is not part of my school system and i've done CodeAcademy tutorials and that's the most i've got about this, I hope you guys can help with my issue.
The variable names is an array and it has all the values from fields.
function getElementArray(divName){
var names = document.getElementsByName("namefield");
}
Nope, you've only got reference to the elements here. You've not got the value yet.
You can get the values by iterating through the names Nodelist array and use names[i].value
The problem is I would like to set these values from array to the
values of another div on the page
If it's going to be in same page, then use innerHTML or textContent property of the DOM to assign the value.
document.getElementById("MAIN").textContent= names[1].value;
Just for demo purpose am using names[1] here so it will load the second input value.
Let's say i have a lot of div's on another page (table.html) but some
of them have id="MAIN". I would like to change the value inside of the
div
Once you move to another page, the javascript state will be lost. So you wont have access to names inside that page.
Either you must store the values into localStorage and retrieve in next page.
Else add the values to query string of your URL and retrive it there.
Edit: Update based on comments
Let us assume you have var names = document.getElementsByName("namefield"); so to store the values inside localStorage.
var myValues = [],
names = document.getElementsByName("namefield");
for(var i = 0; i < names.length; i++) {
myValues.push(names[i].value);
}
localStorage.myValues = JSON.stringify(myValues);
Now if your next page, Iinside window.onload event:
window.onload = function() {
var myValues = localStorage.getItem("myValues") ? JSON.parse(localStorage.getItem("myValues")) : [],
divElements = document.querySelectorAll("#MAIN");
for(var i =0; i < myValues.length; i++) {
divElements[i].textContent = myValues[i];
}
}
If you want to set or change the contents of an element, you can use the innerHTML property.
So in your case, document.getElementById("MAIN").innerHTML = "Whatever you want";
For the record, names in your example technically isn't an array, but a NodeList. See https://developer.mozilla.org/en/docs/Web/API/NodeList#Why_is_NodeList_not_an_Array.3F.

Categories