First of all, here is my Javascript object :
var languages = {
languages: [
{ name: "French", locale: "FR", id: "-1" },
{ name: "English", locale: "IT", id: "-2" },
{ name: "Spanish", locale: "ES", id: "-3" },
{ name: "Zoulou", locale: "ZL", id: "-4" },
{ name: "Italian", locale: "EN", id: "-5" }
]
};
I'm using Mustache.js to generate language buttons:
function generateLanguages(languages) {
var output = $("#languages-output");
var template = "{{#languages}}<button id={{id}}><img src=#FLAG onclick='changeLanguage({{locale}})' /><p>{{name}}</p></button>{{/languages}}";
html = Mustache.render(template, languages);
output.append(html);}
I also have a folder containing all the flags images called flags (e.g flags/English.png).
I'm trying to generate the buttons by adding the corresponding flag.
I really have no idea how to do it, I thought to use the "locale" property of the Javascript object in a for loop and for each locale, create a big switch to choose the right image. If someone can help me ?
http://jsfiddle.net/lBrowz/7w5grype/
A few improvements and ideas:
Move templates to your HTML. That's where they should be. Reference them from JS by their ID. It's a lot easier to modify and think about templates when they are outside of the JavaScript.
Maybe using flags for languages isn't the best choice. Sometimes a language cannot accurately be represented by a flag (see Zulu, which I chose to represent by the flag of Mozambique, but that might not be what your users expect. The same is true for English, when you think about it.)
Anyway, instead of one flag image per language, use a single image that contains all flags and then use CSS sprites to display selected flags. I used this project here: http://tkrotoff.github.io/famfamfam_flags/
Use data-* attributes to store extra information in elements.
Use event delegation to handle clicks. Never use inline event handlers (like onclick).
var languages = {
languages: [
{ name: "French", locale: "FR", id: "-1", cls: "famfamfam-flag-fr" },
{ name: "English", locale: "IT", id: "-2", cls: "famfamfam-flag-gb" },
{ name: "Spanish", locale: "ES", id: "-3", cls: "famfamfam-flag-es" },
{ name: "Zoulou", locale: "ZL", id: "-4", cls: "famfamfam-flag-mz" },
{ name: "Italian", locale: "EN", id: "-5", cls: "famfamfam-flag-it" }
]
};
function changeLanguage(locale) {
$("#locale").text(locale);
}
$(function () {
var languagesTemplate = $("#languages-template").html();
$("#languages-output").html( Mustache.render(languagesTemplate, languages) );
$(document).on("click", ".language-button", function () {
var locale = $(this).data("locale");
changeLanguage(locale);
});
});
.language-button {
width: 5em;
height: 4em;
margin: 3px;
}
.language-button > span {
display: inline-block;
margin: 2px;
}
<link href="http://tkrotoff.github.io/famfamfam_flags/famfamfam-flags.css" rel="stylesheet"/>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.0/mustache.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="languages-output"></div>
<div id="locale"></div>
<script type="text/x-handlebars-template" id="languages-template">
{{#languages}}
<button id="{{id}}" class="language-button" data-locale="{{locale}}">
<span class="{{cls}}"></span>
<span>{{name}}</span>
</button>
{{/languages}}
</script>
Run the code snippet above to see it live.
Related
I have a complex query with 100s of fields and nested fields. What I want to do is, for each Index, extract the English and French text. As you can see in the array, there is no French text for some indexes. In that case I want to get the English text.
For me extracting the English text works fine because the text is already there, but incase of French, I get undefined errors. What would be the best way to implement this. Is Loadash needed for this or just pure JS methods?
Just to be clear, I have erros with extracting french because in some fields, french text is not available, I want to use the english value in that case.
Also It is recommend if I am able to get the English and French values by it's language field rather than the index. I have no idea how to do that.
Any suggestion, documentation is appreciated. Thank you!
example array:
[
{
id: "1",
name: [
{
language: "en-US",
text: "HOLIDAY"
}
],
order: 6,
Groups: [
{
name: [
{
language: "en-US",
text: "REGULAR"
}
],
code: "REGEARN"
},
{
name: [
{
language: "en-US",
text: "CHARGE"
}
],
code: "CHARGE"
}
]
}
]
and here is the code sandbox that reproduces my error:
CODE SAND BOX
https://codesandbox.io/s/javascript-forked-5073j
EDIT:
EXPECTED OUTPUT:
{
key: key,
englishtext: "Value Here",
frenchtext: "Value Here"
}
below is a working code, but issue is it does not work when there is no french language or that field. I get undefined errors. So is it possible I can get the needed data from the language field?
x.map((y) => ({
key: y.id,
name: y.name[0].text,
groupname: y.Groups ? x.Groups[0].name?.[0].text : 'N/A',
}))
Do you expect result like this? If you don't mind lodash.
const _ = require('lodash');
const getNames = (arr) => {
return arr.map((obj) => {
const id = obj.id;
const englishtext = _.get(obj, 'name[0].text', 'N/A');
const frenchtext = _.get(obj, 'name[1].text', englishtext);
return { id, englishtext, frenchtext };
});
};
console.log(getNames(x));
// [
// { id: '1', englishtext: 'HOLIDAY', frenchtext: 'HOLIDAY' },
// { id: '2', englishtext: 'Stat Holiday', frenchtext: 'Congé Férié' },
// { id: '3', englishtext: 'Over', frenchtext: 'Over' }
// ]
I am using KendoUI Scheduler control and here is initialization code
$("#Scheduler").kendoScheduler({
dataSource: [],
selectable: true,
height: 500,
editable: false,
eventTemplate: $("#event-template").html(),
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
resources: [
{
field: "resourceviewid",
name: "ResourceViews",
dataColorField: "key",
dataSource: [
{ text: "Appointments", value: 1, key: "orange" },
{ text: "Delivery Specialist", value: 2, key: "blue" },
{ text: "Orientation Specialist", value: 3, key: "green" }
]
}
],
group: {
resources: ["ResourceViews"],
orientation: "horizontal"
}
});
Here "Appointments" group is default, it will be available always
I have check box in my screen
<div id="divResourceView">
<label><input checked type="checkbox" value="1" />Delivery Specialist</label>
<label><input checked type="checkbox" value="2" />Orientation Specialist</label>
</div>
On change event I wrote below code to get selected values from checkbox and updating GROUP datasource of KendoUI scheduler as below
$("#divResourceView :checkbox").change(function (e) {
var checked = $.map($("#divResourceView :checked"), function (checkbox) {
return parseInt($(checkbox).val());
});
});
var scheduler = $("#Scheduler").data("kendoScheduler");
var arrayOfStrings = checked.toString().split(",");
for (var i = 0; i < arrayOfStrings.length; i++)
{
if(arrayOfStrings[i] == 1)
{
var data = [{ text: "Delivery Specialist", value: 2, color: "blue" }];
scheduler.resources[1].dataSource.data(data);
}
if (arrayOfStrings[i] == 2) {
var data = [{ text: "Orientation Specialist", value: 3, color: "green" }];
scheduler.resources[2].dataSource.data(data);
}
}
scheduler.refresh();
But it removes all groups and add only one. I want to see both groups when arrayOfStrings has values "1,2",
I can see all groups during initialization But it disappears when i check the check box.
Images for reference
During Initialization
After
As you can see clearly, Delivery Specialist is missing in scheduler control
Found some link: http://www.telerik.com/forums/add-filter-to-resource-datasource
But not sure what they talking about? seems like refresh issue.
I have done this I believe you're right and your issue is to do with refreshing, I use the following to refresh it.
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.view(scheduler.view().name);
hope this helps through it is stupidly late (I'm currently looking up how to do this lazerly
So I'm working with a Kendo Grid and how it's headers are grouped. One option that I have working currently is for the Grid to grab my list and sort group by checking every element in that list. So I get something like:
->Roles:
->Roles: Tester, Manager, Team Lead
->Roles: Tester
->Roles: CEO, Tester
->Roles: Team Lead, CEO
(you get the idea). This is because "Roles" in my database model are in a list (since a person can have many roles) and the Kendo Grid is comparing every element in that list. However, I want it to group by just the first element in each person's list so I instead get something like:
->Roles: Tester
->Roles: Manager
->Roles: Team Lead
->Roles:
->Roles: CEO
etc. Does anyone know how to do this? Currently I am doing
group: {
field: "RoleName",
aggregates: [
{ field: "ResourceName", aggregate: "count" },
{ field: "OrganizationName", aggregate: "count" }
]
},
And I assume that I want to be doing something more along the lines of:
group: {
field: "RoleName.get(0)",
aggregates: [
{ field: "ResourceName", aggregate: "count" },
{ field: "OrganizationName", aggregate: "count" }
]
},
However, I'm not familiar enough with Kendo Grid to know the syntax to do this correctly. Thanks in advance for all help!
Edit: I should add that because many of the people that will be using this still need IE8 support, I am using Kendo Grid imports from /2012.2.710 instead of the latest update
*Edit My Answer assumes the user loads the data outside the function and doesn't hard code in the data.
Try using the parse function in schema,
I'll just add to what you should have in your project already, for example:
$('.grid').kendoGrid({
dataSource: {
schema: {
parse: function(data) {
for (var i = 0; i < data.length; i++) {
data[i].firstWord = data[i].name.split(' ')[0];
}
return data;
}
}
group: {
field: "firstWord"
}
},
columns: [{
field: "name"
}, {
field: "firstWord",
hidden: true,
groupHeaderTemplate: "#=value#"
}]
});
This is just a fix over Ryan Hoyle answer's example:
var grid = $('#grid').kendoGrid({
dataSource: {
data: [{
name: 'Hello world'
}, {
name: 'Hello John Doe'
}, {
name: 'Hello Jane Doe'
}, {
name: 'Bye Jane Doe'
}, {
name: 'Bye World'
}],
schema: {
parse: function(data) {
data.forEach(d => d.firstWord = d.name.split(' ')[0]);
return data;
}
},
group: {
field: "firstWord"
}
},
columns: [{
field: "name"
}, {
field: "firstWord",
hidden: true,
groupHeaderTemplate: "#=value#"
}]
}).data().kendoGrid;
<link href="http://kendo.cdn.telerik.com/2016.2.607/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.607/js/kendo.all.min.js"></script>
<div id="grid"></div>
I am new to html and i want to consult you about an issue i have.
I have a json object with this structure (only example):
{
[{
ServerName: "Server1",
TestResults: [{
Name: "Test1",
ErrorMessage: "",
Success: true
},
Name: "Test1", ErrorMessage: "", Success: true
}]
}, {
ServerName: "Server2",
TestResults: [{
Name: "Test1",
ErrorMessage: "",
Success: true
},
Name: "Test1", ErrorMessage: "", Success: true
}]
}]
}
My javascript code gets this object and suppose to create from it something like this:
<ul>
<lh>ServerName</lh>
<li>TestName</li>
<li>TestName</li>
<lh>ServerName2</lh>
<li>TestName</li>
<li>TestName</li>
.....
</ul>
I want to know how do i create such a list that each 'lh' has a line of its own,
and each 2-3 'li' are in the same line.
Can you help me find the best solution for it?
P.S - I am not using a table because it has some problems in jquery mobile that sometimes make it not fitted for the page size.
If I understand correctly, you can add some css for that:
ul>lh{
display: block;
}
ul>li{
display: inline;
}
See this jsfiddle.
Use a definition list (<dl>) and style it with css. Add a unique class to your list to avoid conflict with other CSS styles: jsfiddle
HTML
<dl class="yourclass">
<dt>ServerName</dt>
<dd>TestName</dd>
<dd>TestName</dd>
<dt>ServerName2</dt>
<dd>TestName</dd>
<dd>TestName</dd>
</dl>
CSS
dl.yourclass dd {
display:inline;
}
I would like to create ONE object containing the whole config for certain component. I would liek it too be like this:
var ObjectConfig = {
fieldKeys : {
name: "Obj. name",
state: "Obj. state",
color: "Obj. color"
},
templates : {
basicTemplate : [ ObjectConfig.fieldKeys.name, ObjectConfig.fieldKeys.state ],
altTemplate : [ ObjectConfig.fieldKeys.name, ObjectConfig.fieldKeys.color ]
}
}
But this in the right way to do it - it doesn't work. How can I achieve my goal?
EDIT:
Sorry, I was writing it by hand in a hurry, that's where the syntax errors came from. Now it's correct. The error I get is Uncaught TypeError: Cannot read property 'fieldKeys' of undefined. I guess that doing it this way is impossible - what is the best alternative then?
Your problem is that the object is constructed from the literal before it is assigned to the ObjectConfig variable. Therefore, accessing ObjectConfig.fieldKeys inside the literal will lead to the error.
The best solution is to construct first one object only, and then add further properties sequentially:
var ObjectConfig = {
fieldKeys: {
name: "Obj. name",
state: "Obj. state",
color: "Obj. color"
}
};
ObjectConfig.templates = {
basicTemplate: [ ObjectConfig.fieldKeys.name, ObjectConfig.fieldKeys.state ],
altTemplate: [ ObjectConfig.fieldKeys.name, ObjectConfig.fieldKeys.color ]
};
Another (shorter) method would an extra variable for the keys object, which is assigned before the construction of the templates object:
var keys, ObjectConfig = {
fieldKeys: keys = {
name: "Obj. name",
state: "Obj. state",
color: "Obj. color"
},
templates: {
basicTemplate: [ keys.name, keys.state ],
altTemplate: [ keys.name, keys.color ]
}
};
To work around the extra variable in global scope, you might use an IEFE. A more readable solution might look like this then:
var ObjectConfig = (function() {
var keys = {
name: "Obj. name",
state: "Obj. state",
color: "Obj. color"
};
return {
fieldKeys: keys,
templates: {
basicTemplate: [ keys.name, keys.state ],
altTemplate: [ keys.name, keys.color ]
}
};
})();