Find element by data attributes that use "|" as separators - javascript

Fiddle Example
HTML markup:
<div data-id='23|24|25'></div>
<div data-id='29|30|31'></div>
Script:
var array = [
{
"mid": "24"
},
{
"mid": "26"
},
{
"mid": "28"
},
{
"mid": "29"
},
{
"mid": "30"
},
{
"mid": "31"
}
];
var item_html ="";
$.each(array,function(i,k) {
item_html = '<h3>'+k["mid"]+'</h3>';
$('div[data-id="'+k["mid"]+'"').append(item_html); ???????????
});
Would it be possible to find the div element if part of the "|" separated value in its data-id matches the mid?
I'm trying to get an output like this:
<div data-id='23|24|25'>
<h3>24</h3>
</div>
<div data-id='29|30|31'>
<h3>29</h3>
<h3>30</h3>
<h3>31</h3>

You should use the *= selector (contains):
$('div[data-id*="'+k["mid"]+'"').append(item_html);

The result you are looking for is something tricky. I have update your code. hope this will help you.
var array = [
{ "mid": "24"},
{"mid": "26"},
{"mid": "28"},
{"mid": "29"},
{"mid": "30"},
{"mid": "31"}
];
$('[data-id]').each(function(){
var $this = $(this), dataArr = $this.data('id').split('|'), i = 0;
for(;i< dataArr.length; i++) {
if(numInObjArr(array,dataArr[i])) {
$this.append('<h3>'+ dataArr[i] +'</h3>');
}
}
});
//function to check number in array object provided above
function numInObjArr(objArr, num){
for (var i = 0, len=objArr.length; i< len; i++){
if(objArr[i]["mid"] == num) {
return true;
}
}
return false;
}
http://jsfiddle.net/EZ56N/73/ to see the working example

Related

next and previous JSON data with javascript

I' would like to create Next/Previous buttons for json array, but I can't get it to work.
This is the last one I have tried
<div id="text"></div>
<button name="prev">go to previous div</button>
<button name="next">go to next div</button>
<script>
myFunction([
{
"text": "text0"
},
{
"text": "text1"
},
{
"text": "text2"
},
{
"text": "text3"
}
]);
function myFunction(arr) {
var out = "";
var i ;
out = '<p>' + arr[i].text + '</p> <br>';
document.getElementById("text").innerHTML = out;
}
</script>
You can convert json data to string or better say html with $.each like below. as you tagged jQuery, here is jQuery approach:
myFunction([{
"text": "text0"
},
{
"text": "text1"
},
{
"text": "text2"
},
{
"text": "text3"
}
]);
function myFunction(arr) {
$.each(arr, function(i, v) {
$('#text').append('<div>' + v.text + '</div>');
});
}
var divs = $('.mydivs>div');
var now = 0;
divs.hide().first().show();
$("button[name=next]").click(function(e) {
divs.eq(now).hide();
now = (now + 1 < divs.length) ? now + 1 : 0;
divs.eq(now).show();
});
$("button[name=prev]").click(function(e) {
divs.eq(now).hide();
now = (now > 0) ? now - 1 : divs.length - 1;
divs.eq(now).show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="text" class="mydivs"></div>
<button name="prev">go to previous div</button>
<button name="next">go to next div</button>
<div id="text">
</div>
<script>
var i = 0;
let arr = [
{
"text": "text0"
},
{
"text": "text1"
},
{
"text": "text2"
},
{
"text": "text3"
}
];
setInterval(function myFunction() {
var out = "";
out = '<p>' + arr[i].text + '</p> <br>';
document.getElementById("text").innerHTML = out;
console.log(out);
if (i < arr.length - 1) {
i += 1;
} else {
i = 0;
}
}, 1000)
</script>

Create search list based on data from array

I have an array that should be used to create a list of search engines next to a search field.
I have this script which is working. However, it generates a select box of options - you enter a search phrase, select engine, and then get a result. However, since I have to change the markup to be using Bootstrap, I need to change the select box to an unordered list, like this:
<ul class="dropdown-menu">
<li class="selected">Select</li>
<li>Google</li>
<li>Nyheder</li>
<li>Studier</li>
</ul>
If I try to change the select into <ul id="global_search_filter" class="search_filter"></ul> and var option = jQuery(document.createElement("option")); to var option = jQuery(document.createElement("li"));the scripts breaks.
How can I achieve the same functionality but change the markup from a select box to an unordered list with list options?
I have created a fiddle here.
Maybe someone can point me in the right direction on how to solve this.
el = document.getElementById("localdomain");
el.value = window.location.hostname;
if (!window.searchEngines) {
window.searchEngines = [{
"url": "https://www.google.com",
"label": "Google",
"querykey": "q",
"id": "allWeb"
}, {
"url": "https://www.bing.com",
"label": "Bing",
"querykey": "q",
"id": "bing",
"param": {
"doctype": "",
"path": "",
"cms_mode": ""
}
}, {
"url": "https://www.yahoo.com",
"label": "Yahoo",
"querykey": "q",
"id": "yahoo",
"param": {
"gcse": "014167723083474301078:sxgnobjpld4"
}
}];
}
window.searchCallbacks = [];
jQuery(function() {
var stripPath = function(path) {
return path === "/" ? path : path.replace(/\/$/, "");
};
var isEngineCurrent = function(engine) {
if (stripPath(engine.url) !== stripPath(document.location.origin + document.location.pathname)) {
return false;
}
if (engine.param) {
for (var key in engine.param) {
if (getUrlParameter(key) !== engine.param[key]) {
return false;
}
}
}
return true;
};
var forms = jQuery("form.search_form");
forms.each(function() {
var form = jQuery(this);
var field = form.find("input.search_query");
var filter = form.find(".search_filter");
var resetForm = form.hasClass("search_reset");
if (window.searchEngines) {
for (var i = 0; i < window.searchEngines.length; i++) {
var engine = window.searchEngines[i];
var option = jQuery(document.createElement("option"));
option.text(engine.label);
option.val(i);
if (!resetForm && isEngineCurrent(engine)) {
option.attr("selected", "selected");
field.val(getUrlParameter(engine.querykey));
}
filter.append(option);
}
form.submit(function(event) {
var chosenEngine = window.searchEngines[filter.val()];
form.attr("action", chosenEngine.url);
form.attr("method", chosenEngine.method || "GET");
field.attr("name", chosenEngine.querykey);
if (chosenEngine.param) {
for (var paramName in chosenEngine.param) {
var input = jQuery(document.createElement("input"));
input.attr("type", "hidden");
input.attr("name", paramName);
input.val(chosenEngine.param[paramName]);
form.append(input);
}
}
for (var i = 0; i < window.searchCallbacks.length; i++) {
var callback = window.searchCallbacks[i];
if (jQuery.isFunction(callback)) {
callback(chosenEngine, this);
}
}
});
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="global_search_form" class="search_form search_reset" target="_blank">
<input type="text" id="global_search_query" class="search_query" placeholder="Search where...?">
<input id="localdomain" name="localdomain" type="hidden" value=" + window.location.hostname + ">
<select id="global_search_filter" class="search_filter"></select>
<button name="sa" id="submit-button" type="submit">Search</button>
</form>
Working Jsfiddle.
Here is a modified version of your code(unfortunately you can't submit a form on Stack Overflow, but you can test the jsfiddle above). Will update imediatelly with explications:
UPDATE:
Ok, so let's see what we have done here:
First we replace the select with an ul container
We append li elements to the ul parent
We add the data-selected custom attribute on every li element with empty value except the first one which we add the selected value.
We add the data-value attribute to the li element to replicate the value like when we have a select option value.
On click of a dynamically added li element we bind the click event dinamically using event delegation to add the selected attribute value.
On click of the li element we also add the selected value name to the Bootstrap button.
el = document.getElementById("localdomain");
el.value = window.location.hostname;
if (!window.searchEngines) {
window.searchEngines = [{
"url": "https://www.google.com",
"label": "Google",
"querykey": "q",
"id": "allWeb"
}, {
"url": "https://www.bing.com",
"label": "Bing",
"querykey": "q",
"id": "bing",
"param": {
"doctype": "",
"path": "",
"cms_mode": ""
}
}, {
"url": "https://www.yahoo.com",
"label": "Yahoo",
"querykey": "q",
"id": "yahoo",
"param": {
"gcse": "014167723083474301078:sxgnobjpld4"
}
}];
}
window.searchCallbacks = [];
jQuery(function() {
var stripPath = function(path) {
return path === "/" ? path : path.replace(/\/$/, "");
};
var isEngineCurrent = function(engine) {
if (stripPath(engine.url) !== stripPath(document.location.origin + document.location.pathname)) {
return false;
}
if (engine.param) {
for (var key in engine.param) {
if (getUrlParameter(key) !== engine.param[key]) {
return false;
}
}
}
return true;
};
$(document).on('click', 'li', function() {
$('li[data-selected="selected"]').attr('data-selected', '');
$(this).attr('data-selected', 'selected');
$("#menu").text($(this).text());
$("#menu").val($(this).text());
})
var forms = jQuery("form.search_form");
forms.each(function() {
var form = jQuery(this);
var field = form.find("input.search_query");
var filter = form.find(".dropdown-menu");
var resetForm = form.hasClass("search_reset");
if (window.searchEngines) {
for (var i = 0; i < window.searchEngines.length; i++) {
var engine = window.searchEngines[i];
var option = jQuery(document.createElement("li"));
option.text(engine.label);
option.attr('data-value', i);
if (i == 0) {
option.attr('data-selected', 'selected');
} else {
option.attr('data-selected', '');
}
option.attr('role', 'presentation');
if (!resetForm && isEngineCurrent(engine)) {
option.attr("selected", "selected");
field.val(getUrlParameter(engine.querykey));
}
filter.append(option);
}
form.submit(function(event) {
var chosenEngine = window.searchEngines[$('li[data-selected="selected"]').data('value')];
console.log(chosenEngine);
form.attr("action", chosenEngine.url);
form.attr("method", chosenEngine.method || "GET");
field.attr("name", chosenEngine.querykey);
if (chosenEngine.param) {
for (var paramName in chosenEngine.param) {
var input = jQuery(document.createElement("input"));
input.attr("type", "hidden");
input.attr("name", paramName);
input.val(chosenEngine.param[paramName]);
form.append(input);
}
}
for (var i = 0; i < window.searchCallbacks.length; i++) {
var callback = window.searchCallbacks[i];
if (jQuery.isFunction(callback)) {
callback(chosenEngine, this);
}
}
});
}
});
});
li[data-selected="selected"] {
color: #F00;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<form id="global_search_form" class="search_form search_reset" target="_blank">
<input type="text" id="global_search_query" class="search_query" placeholder="Search where...?">
<input id="localdomain" name="localdomain" type="hidden" value=" + window.location.hostname +">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="menu" data-toggle="dropdown">Choose option
<span class="caret"></span></button>
<ul class="dropdown-menu" role="menu" aria-labelledby="menu">
</ul>
</div>
<button name="sa" id="submit-button" type="submit">Search</button>
</form>

Making calculations from nested arrays in AngularJS

I have the following array:
$scope.products = [
{
nom : "Pa de fajol",
img : "dill1.jpg",
descripcio: [
"Pa de motlle"
],
preu:4.90,
tipus: "Pa"
},
{
nom : "Pagès semi integral de blat/espelta",
img : "dill2.jpg",
descripcio: [
"Pa de pagès",
"680g / 400g"
],
tipus: "Pa",
variacions : [
{
nom: "Gran",
preu: "3.70",
grams: "680g",
basket: 0
},
{
nom: "Petit",
preu: "2.30",
grams: "400g",
basket: 1
}
]
}
In the frontend I display it with an ng-repeat and depending if the product has price (preu) or not, I display one input for quantity for single product, or one input for each variation.
Looks like this:
<div ng-repeat="pa in products">
<div ng-if="!pa.preu" ng-repeat="vari in pa.variacions">
<input type="number" ng-model="pa.variacions.basket" ng-init="pa.variacions.basket=0">
</div>
<input ng-if="pa.preu" type="number" ng-model="pa.basket" name="basket" ng-init="pa.basket=0">
</div>
<a ng-click="insert()">Add to cart</a>
When I trigger insert(), I have a function that will add the products and calculate the total price, but so far it only works for products with a price, not for the variations.
The function looks like this:
$scope.insert = function() {
$scope.singleorder = [];
for(var i = 0; i < $scope.products.length; i++)
if($scope.products[i].basket) { // if input has been setted
$scope.singleorder.push({
'product': $scope.products[i].nom,
'number': $scope.products[i].basket,
'preu': ($scope.products[i].preu * $scope.products[i].basket)
});
}
console.log($scope.singleorder);
}
How would I have to proceed to include in the $scope.singleorder array also the calculations from the nested array of variations?
Any tips?
EDIT
See Plunkr to reproduce the issue
SOLUTION
I managed to fix it with the help of some comments!
See Plunkr for final version.
Here's the final function:
$scope.insert = function() {
$scope.singleorder = [];
for(var i = 0; i < $scope.products.length; i++)
if($scope.products[i].basket) { // if input has been setted
$scope.singleorder.push({
'product': $scope.products[i].nom,
'number': $scope.products[i].basket,
'preu': ($scope.products[i].preu * $scope.products[i].basket)
});
}
else if($scope.products[i].variacions) { // if input has been setted
angular.forEach($scope.products[i].variacions, function(variacions) {
if(variacions.basket) {
$scope.variname = $scope.products[i].nom + ' (' + variacions.nom + ')'
$scope.singleorder.push({
'product': $scope.variname,
'number': variacions.basket,
'preu': (variacions.preu * variacions.basket)
});
}
});
}
console.log($scope.singleorder);
Your issue was that your variacions is an array use this,
$scope.insert = function() {
$scope.singleorder = [];
for(var i = 0; i < $scope.products.length; i++)
if($scope.products[i].basket) { // if input has been setted
$scope.singleorder.push({
'product': $scope.products[i].nom,
'number': $scope.products[i].basket,
'preu': ($scope.products[i].preu * $scope.products[i].basket)
});
}
else if($scope.products[i].variacions) { // if input has been setted
for(var j=0;j<$scope.products[i].variacions.length; j++){
$scope.singleorder.push({
'product': $scope.products[i].variacions[j].nom,
'number': $scope.products[i].variacions[j].basket,
'preu': ($scope.products[i].variacions[j].preu * $scope.products[i].variacions[j].basket)
});
}
}
console.log($scope.singleorder);
}
See Plunkr

DataTable with dropdown Column

I need to make dropdown as column in DataTable jQuery it is lookinng like as below right now
And I want it like the below image
and the code which I use is
<table id="example" class="hover row-border dataTable" role="grid" width="100%">
<thead class="dataTableHeader">
<tr>
<th>Days</th>
<th>Start Time</th>
<th>End Time</th>
</tr>
</thead>
</table>
$(document).ready(function () {
$('#example').DataTable({
"aaData": OrganizationData.OrganizationPreference.ScheduleDaysCol,
"columns": [
{"data": "DayName"},
{"data": "StartDateHour"},
{"data": "EndDateHour"}
],
"paging": false,
"ordering": false,
"info": false,
"filter": false
});
});
Another way would be to use the render method:
"render": function(d,t,r){
var $select = $("<select></select>", {
"id": r[0]+"start",
"value": d
});
$.each(times, function(k,v){
var $option = $("<option></option>", {
"text": v,
"value": v
});
if(d === v){
$option.attr("selected", "selected")
}
$select.append($option);
});
return $select.prop("outerHTML");
}
Working example.
You can use this way then for the dropdown setting
"aaData": OrganizationData.OrganizationPreference.ScheduleDaysCol,
"columnDefs": [{ "targets": 0,"data": "DayName" },
{
"targets": 1,
"data": "StartDateTime",
"render": function (data, type, full, meta) {
var $select = $("<select></select>", {
});
$.each(times, function (k, v) {
var $option = $("<option></option>", {
"text": v,
"value": v
});
if (data === v) {
$option.attr("selected", "selected")
}
$select.append($option);
});
return $select.prop("outerHTML");
}
DataTables seem to have an editor for this type of thing as refrenced by Samyukta and others: https://editor.datatables.net/examples/inline-editing/simple
I would say that is the easiest answer. It is however, a commercial extension with a free trial only.
If you wanted some jquery code to simply change the static times to dropdown boxes, you could give this a shot:
//utility functions to get half-hour increment lists
function getTimeList(){
var iterations = 48;
var result = [];
for(int i = 0; i < iterations; i++){
var hour = Math.floor(i / 2);
var minute = (i % 2) > 0 ? '30' : '00';
result.push(hour + ':' + minute);
}
return result;
}
function getOptionTimeList(){
var raw = getTimeList();
var iterations = raw.length;
var result = '';
for(int i = 0; i < iterations; i++){
result = result + '<option>' + raw[i] + '</option>';
}
return result;
}
//I'm using the not selector to avoid changing the days into dropdown by accident
$('#example tbody tr td:not(#example tbody tr:first-child)').each(
function(index, element){
var value = element.innerHTML;
var optionList = getOptionTimeList();
var replacement = '<td><select>' + optionList + '</select></td>';
$(element).replaceWith(replacement)
}
);
This should get you the drop down boxes where you need them. I'll revise this if you have problems with it.
You can try to use this, this is what i'm using now.
https://github.com/ejbeaty/CellEdit
Look at this example:
"inputTypes": [
{
"column":0,
"type":"text",
"options":null
},
{
"column":1,
"type": "list",
"options":[
{ "value": "1", "display": "Beaty" },
{ "value": "2", "display": "Doe" },
{ "value": "3", "display": "Dirt" }
]
}
Hope it help someone.

Output array to element classes

I'm trying to output a JSON object to different parts of an HTML page using the same classes.
I'm importing my JSON from an API but when I've put information into it (via input fields) it looks a little bit like this:
{
"trip": [
{ // the first object in the trip-array
"leg": [{
"tripid": "0",
"origin": {
"name": "New York",
"time": "12:04"
},
"destination": {
"name": "Albany",
"time": "1:49"
}
},{
"tripid": "1",
"origin": {
"name": "Albany",
"time": "2:05"
},
"destination": {
"name": "Boston",
"time": "3:12"
}
}]
},
{ // the second object in the trip-array
"leg": [{
"tripid": "0",
"origin": {
"name": "New York",
"time": "1:04"
},
"destination": {
"name": "Albany",
"time": "2:49"
}
},{
"tripid": "1",
"origin": {
"name": "Albany",
"time": "3:05"
},
"destination": {
"name": "Boston",
"time": "4:12"
}
}]
}]
}
I'm trying to display the information on my website, but I can't get it to behave the way I want it to.
The first time around I did it something like this (after fetching the JSON via my PHP-page):
function addDataToHTML(data){
var trips = data.trip;
$.each(trips, function(){
document.getElementById('show_all_results');
var summary = document.createElement('div');
summary.innerHTML = "<span class='origin_time'>" + this.leg[0].origin.time +
" </span><span class='origin_name'> " + this.leg[0].origin.name +
"</span><span>-</span><span class='destination_time'>" + this.leg[leg.length-1].destination.time +
" </span><span class='destination_name'> " + this.leg[this.leg.length-1].destination.name +
"</span>";
document.getElementById('show_all_results').appendChild(summary);
});
}
This works but the problem I'm having is that I want to add a button in the code which would give me more information via a display:block/none-functionality. The button (and the rest of the information) would be created similarly with me having to write it in the innerHTML part of the JS, but all the ways that I've tried haven't worked and I guess it's all about me creating the divs and other DOM objects in the JS code which means that the HTML doesn't really recognize them.
Anyhow, to get more control of the code I'm now trying something like this with the HTML:
<div id="show_all_results">
<div id='search_result_single'> // First results....
<div id='search_result_from_box'>
<span class="origin_time"></span>
<span class="origin_name"></span>
</div>
<div id='search_result_divider'>
<span>-</span>
</div>
<div id='search_result_to_box'>
<span class='destination_time'></span>
<span class='destination_name'></span>
</div>
</div>
<div id='search_result_single'> // Second results....
<div id='search_result_from_box'>
<span class="origin_time"></span>
<span class="origin_name"></span>
</div>
<div id='search_result_divider'>
<span>-</span>
</div>
<div id='search_result_to_box'>
<span class='destination_time'></span>
<span class='destination_name'></span>
</div>
</div>
...and so on.
</div>
The JS:
for (var i = 0; i < this.leg.length; i++) {
var originName = document.getElementsByClassName("origin_name");
var originTime = document.getElementsByClassName("origin_time");
var destTime = document.getElementsByClassName("destination_time");
var destName = document.getElementsByClassName("destination_name");
for (var x = 0; x < originName.length; x++) {
var originNameItem = originName[x];
originNameItem.innerHTML = this.leg[0].origin.name;
}
for (var y = 0; y < originTime.length; y++) {
var originTimeItem = originTime[y];
originTimeItem.innerHTML = this.leg[i].origin.time;
}
for (var z = 0; z < destTime.length; z++) {
var destTimeItem = destTime[z];
destTimeItem.innerHTML = this.leg[this.leg.length - 1].destination.time;
}
for (var a = 0; a < destName.length; a++) {
var destNameItem = destName[a];
destNameItem.innerHTML = this.leg[this.leg.length - 1].destination.name;
}
}
Is there anybody that can help me get each part of the leg-array into different parts of the page using the same classes as I've done? Or is there a better way?
This became really long, sorry about that, but please let me know if I can provide any additional information. Thanks!

Categories

Resources