I'm trying to populate a div dynamically with data from JSON but want to avoid duplicates. The script below will give me 3 divs, 2 "standard" and one "special".
How can I achieve without creating duplicate div?
var productList = [
{
model:"helskap",
type:"special",
family:"Bravo"
},
{
model:"Z-skap",
type:"standard",
family:"Valhalla"
},
{
model:"smafacksskap",
type:"standard",
family:"Jona"
}
];
$.each(productList, function(i, item) {
$('.filter').append('<div class="' + productList[i].type+ '"><input type="radio" name="type" value="' + productList[i].type+ '" /><label>' + productList[i].type+ '</label></div>')
});
<div class"filter"></div>
The better way is to first get the array with unique objects on property type then you can use that new filtered array for rendering like in filterProductList:
var productList = [{
model: "helskap",
type: "special",
family: "Bravo"
},
{
model: "Z-skap",
type: "standard",
family: "Valhalla"
},
{
model: "smafacksskap",
type: "standard",
family: "Jona"
}
];
var filterProductList = productList.reduce((acc, item) => {
var existItem = acc.find(({type}) => type === item.type);
if (!existItem) {
acc.push(item);
}
return acc;
}, []);
console.log(filterProductList);
Then use filterProductList to render the HTML in your page. Your code will look:
$.each(filterProductList, function(i, item) {
var type = filterProductList[i].type;
$('.filter').append('<div class="' + type + '"><input type="radio" name="type" value="' + type + '" /><label>' + type + '</label></div>')
});
I think the easy way is to create each div with id="type", then append contents to div id="type".
Related
I have a JSON array in a JSON file looks like this:
{
"states": [
{
"state": "Andhra Pradesh",
"districts": [
"Anantapur",
"Chittoor",
"East Godavari",
"Guntur",
"Krishna",
"Kurnool",
"Nellore",
"Prakasam",
"Srikakulam",
"Visakhapatnam",
"Vizianagaram",
"West Godavari",
"YSR Kadapa"]
}
]
}
and I am successfully able to load all states in the select element as a dependent select option
. when I select a state from a select element it populates a related array in the district select element.
but instead of the array showing a separate option it shows as one option:
Should I modify my JSON array in a different format?
jquery
$('#statePicker').on('change', function() {
$("#cityPicker").html('');
$.ajax({
url: "{{ asset('json/in-sc-list.json') }}",
type: "GET",
dataType: 'json',
success: function(res) {
$('#cityPicker').html('<option value="">Select City</option>');
$.each(res.states, function(key, value) {
if (value.state == $('#statePicker').val()) {
console.log(value.districts);
$("#cityPicker").append('<option value="' + value
.districts + '">' + value.districts + '</option>');
}
});
}
});
});
blade
<span>
<select id="statePicker" name="statePicker" required class="form-control"></select>
<select id="cityPicker" name="cityPicker" required class="form-control"></select>
</span>
Your data structure is fine. The issue is that you're not creating multiple option elements, you're only creating one. This part is off:
$("#cityPicker").append('<option value="' + value
.districts + '">' + value.districts + '</option>');
}
What you want to do is create an option element for each district, as follows:
for (const district of value.districts) {
$("#cityPicker").append('<option value="' + district + '">' + district + '</option>');
}
let statePicker = $('#statePicker').val();
let list = $("#cityPicker");
$.each(res.states, function(key, value) {
if (value.state == statePicker) {
$.each(items, function(item) {
list.append(new Option(item, item));
});
}
});
You need to loop value.districts because its an array, and also, you are doing it in a dirty way, you are initializing $("#cityPicker") on every loop, This might give some performance issues in future if the list items increases.
I have dynamic form elements and trying to add values to input's value attribute which is coming from as a array. However sometimes there are no any data ,then javascript prints undefined to value area of the input element.
How can i check it and dont print undefined in dynamic element?
$("#test").append("<input type='text' name='first-test' class='form-control' value='"+testarray['first-test']+"' >
When we check the textbox , it shows "undefined" as a value.
I think this will work
$("#test").append("<input type='text' name='first-test' class='form-control' value='"+(testarray['first-test']===undefined ? "Insert here what ever you want when it is empty.":testarray['first-test'])+"'>");
https://jsfiddle.net/b51gq0mq/2/
Here is working example, we pass an array with objects into our function. For loop simply skips if value is not found.
var yourArray = [
{ name: 'Janet' },
{ name: 'Jane', value: 1 },
{ name: 'Tom', value: 2 },
{ name: 'Kate', value: 3},
{ name: 'Mark' },
{ name: 'Tom' }
];
function addInputs(array) {
for (i = 0; i < array.length; i++) {
var element = array[i];
// Skips if no value found
if (element.value === undefined) {
continue;
}
var html = '<input type="text" name="' + element.name + '" class="form-control" value="' + element.value + '" />';
$('#test').append(html);
}
};
addInputs(yourArray);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test"></div>
This is my JSON file:
{
"AL2": {
"3810": "AL2GR1",
"3814": "AL2GR2",
"3815": "AL2GR3",
},
"AN3": {
"3818": "AN3GR1",
"3819": "AN3GR2"
},
"CME": {
"2405": "CME"
}
I need to populate two select boxes. The first one let choose between first level values (AL2,AN3,CME) and the second one between the deep level ones (AL2GR#,AN3GR#,CME).
My infile Javascript is :
var jsonData = {"AL2": {"3810": "AL2GR1","3814": "AL2GR2","3815": "AL2GR3"},"AN3": {"3818": "AN3GR1","3819": "AN3GR2"},"CME": {"2405": "CME"}};
$(window).load(function(){
$.each(jsonData,function(key, value) {
$('#ue').append('<option value=' + key + '>' + key + '</option>');
});
});
function grfromue(element,jsonData) {
var ue = $("#ue option:selected").text();
alert(ue);
$.each(jsonData[ue],function(key, value) {
$('#gr').append('<option value=' + key + '>' + value + '</option>');
});
};
And HTML :
<select id="ue" onChange="grfromue(this,jsonData);">
</select>
<select id="gr">
</select>
The second select box isn't changing, what am I doing wrong ?
Below snippet of code might be helpful to you
var json = {
"AL2": {
"3810": "AL2GR1",
"3814": "AL2GR2",
"3815": "AL2GR3",
},
"AN3": {
"3818": "AN3GR1",
"3819": "AN3GR2"
},
"CME": {
"2405": "CME"
}
};
to get each value in first level
$.each( json, function( key, value ) {
console.log( key );
});
to get second level values based on your first input
input = 'AL2';
$.each( json[input], function( key, value ) {
console.log( key + ' : ' + value );
});
Hope this helps you.
You can use a nested JQuery each method to iterate over the objects and the nested objects within them. You can extend it for as many nested objects as you like.
jQuery.each(obj, function(i, val) {
console.log("Object: " + i);
jQuery.each(val, function(j, value) {
console.log('It has ' + j + ' with value ' + value);
});
});
If you want to populate the second select box based on the value of the first, you can use array notation to fetch contents of the object. Something like this:
jQuery("#selec-id").change(function(){
$("#second-select-id").html("");
jQuery.each(obj[$(this).val()], function(key, value) {
$("#second-select-id").append("<option value='"+key+"'>"+value+"</option>");
});
});
I have a JSON object that I use as a Template for all available Fields that can be added to an element in my Object that is used to Store the values.
I have another Object that holds values. The k,v of this Object storing all the values was not generated in my application. It is handed to me and I need to populate that value in a form that is created dynamically based on my JSON which defines all availabl keys for a given element. Its best I show you my demo app.
Demo: http://jsfiddle.net/bGxFC/15/
1. Click "Button_2" label - Notice how it populates a form with 5 k,v inputs
2.Now click "Button_1" label - Notice how this has 6 k,v inputs
3. Both of these are "Type": "Button" but "Button_2" is missing 'Transition' from its inputs
4This is where my 'var controls' object comes in. It defines all the available option that each type can have.
The Problem
I need to alter my code to use the values from 'objStr' and place them into a form that was created by 'controls'. And once I add a value to an empty input(i.e.The 'Transition' input in "Button_2") it will be saved back to 'objStr'.
Here is my code:
var controls = {
"Button":{"Type": "", "Transition": "","BackgroundImage": "","Position": "","Width": "","Height": ""},
"Image":{"Type": "","BackgroundImage": "","Position": "","Width": "","Height": ""},
"Label":{"Type": "","Position": "","Width": "","Height": "","Text": "","FontSize":"","Color": "", "FontType": ""}
};
objStr = {
"View_1":
{
"Image_1":{
"Type":"Image",
"BackgroundImage":"Image.gif",
"Position":[0,0],
"Width":320,
"Height":480
},
"Button_1":{
"Type":"Button",
"BackgroundImage":"Button.gif",
"Transition":"View2",
"Position":[49,80],
"Width":216,
"Height":71
},
"Button_2":{
"Type":"Button",
"BackgroundImage":"Button2.gif",
"Position":[65,217],
"Width":188,
"Height":134},
"Label_1":{
"Type":"Label",
"Position":[106,91],
"Width":96,
"Height":34,
"Text":"Button",
"FontSize":32,
"Color":[0.12549,0.298039,0.364706,1]
}
}
};
$(document).ready(function () {
var $objectList = $('<div id="main" />').appendTo($('#main'));
$.each(objStr.View_1, function(k, v) {
$('<div/>').append(k).appendTo($objectList).on('click', function(){
var $wrapper = $('#form .wrapper').empty();
if(typeof v === 'string') {
$('<div class="item" />').append('<span class="key">' + k + '</span>' + '<input value="' + v + '"/>').appendTo($wrapper);
}
else {//object
$('<h3 class="formHeading" />').append(k).appendTo($wrapper);
$.each(v, function(key, val) {
$('<div class="item" />').append('<span class="key">' + key + '</span>' + '<input value="' + val + '"/>').appendTo($wrapper);
});
}
$("<button>Save</button>").appendTo($wrapper).on('click', function() {
if(typeof v === 'string') {
v = $(this).closest(".wrapper").find("input").val();
}
else {//object
$(this).closest(".wrapper").find(".item").each(function(i, div) {
var $div = $(div),
key = $div.find(".key").text(),
val = $div.find("input").val();
v[key] = val;
});
}
});
});
});
});
How do I get the options from another set of options.
JS Fiddle Example
at the moment this is outputting the name of each option in opt.social. Instead I want it to fetch the actual HTML related to each option name.
Thus the idea is that in the future when a new social media site is built, this can easily be added via the plugin options without the need to edit the plugin.
Example:
$.each(opt.social, function(index, value) {
html += "<li>" + value.name + "</li>";
});
I have tried
opt[value.name];
opt.value.name;
opt(value.name);
Full example:
(function ($) {
$.fn.socialMedia = function (options) {
// default configuration properties
var defaults = {
social: [
{ name: "facebook.like_large"},
{ name: "twitter.large"},
{ name: "googlePlus.large"}
],
facebook: {
like_large: '<div class="fb-like" data-href="{url}" data-send="false" data-layout="box_count" data-width="120" data-show-faces="false"></div>',
like_small: '<div class="fb-like" data-href="{url}" data-send="false" data-layout="button_count" data-width="120" data-show-faces="false" data-colorscheme="dark"></div>',
share: '<a name="fb_share" type="box_count" share_url="{url}" href="http://www.facebook.com/sharer.php?u={url}&t={title}">Share</a>'
},
twitter: {
large: 'Tweet',
small: 'Tweet'
},
googlePlus: {
large: '<div class="g-plusone" data-size="tall" data-href="{url}"></div>',
small: '<div class="g-plusone" data-size="medium" data-annotation="inline" data-width="120" data-href="{url}"></div>'
}
};
var opt = jQuery.extend(defaults, options);
// Generate HTML
$(this).append(generateHtml());
function generateHtml() {
var html = '<ul>';
$.each(opt.social, function(index, value) {
html += "<li>" + value.name + "</li>";
});
html += '</ul>';
return html;
}
}
$("body").socialMedia();
})(jQuery);
In that code, opt.social is an array of objects, each with a "name" property.
Thus,
var firstOptName = opt.social[0].name;
And so on. The opt.social array should be indexed numerically. Now, opt.googlePlus is just an object with (in this case) two properties, so there's no array indexing involved:
var googleLarge = opt.googlePlus.large;
edit — if you want to just alter that loop to show the HTML:
$.each(opt.social, function(index, value) {
var parts = value.name.split('.'), partVal = opts;
for (var i = 0; i < parts.length; ++i)
partVal = partVal[parts[i]];
html += "<li>" + partVal + "</li>";
});
The trick is that those "name" properties are in the form of dotted "paths" through an object graph, and JavaScript does not have a built-in way of interpreting those. The code I wrote above walks through the object part by part (parts are separated by "." characters), starting from the outer "opts" object.
I've updated your fiddle, according to what I understood you wanted.
each social entry can contain the name of the social service and a default widget to use.
so your defaults can be like this:
social: [
{ name: 'facebook', widget : 'like_large'},
{ name: 'twitter', widget : 'large'},
{ name: 'googlePlus', widget : 'large'}
]
and your generateHTML() can be:
$.each(opt.social, function(index, value) {
var default_widget = opt[value.name][value.widget];
html += "<li>" + default_widget + "</li>";
// or maybe:
html += $('<li></li>').html(default_widget);
});