How to iterate over a div enyos component? - javascript

enyo.kind({
name: "Usr",
kind: enyo.Control,
published: {
username: "",
ToDo: [],
Done:[]
},
components: [
{tag:"title",name:"username"},
{tag:"input", name:"desc", placeholder: "to do..",
style:"width:500px; static: left; padding-right: 10px"},
{tag: "button", content: "New Task", ontap: "addTask",
style:"float: right; padding-left: 10px;
background-color:orange; color:white" },
{tag: "div", name: "ToDo" }
],
addTask: function(inSource, inEvent) {
this.createComponent({
kind: Task,
container: this.$.ToDo,
text: this.$.desc.hasNode().value,
state: "To do"
});
this.$.ToDo.render();
}
})
So, this is what i have. As you can see, I create new elements (Task kind is defined in other js file, doesn´t really matters) using (addTask) and putting them inside the ToDo "div" component. How can I iterate over those elements? something like a 'for each' sentence or so, maybe is there a $'div'.length property or something? I haven´t found an answer in any official documentation.

Related

append div with additional functon

I have an odd task. I am simply trying to add an additonal function on an element when its clicked. I cant seem to trigger the addScroll function that is found within my methods. As you can see, the div should be appended to the screen when the button is clicked. Once that div is clicked as well, the remove method is applied and I also want to apply the addScrollBack().
new Vue({
el: "#app",
data: {
chocs: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
]
},
methods: {
addScrollBack: function(){
alert("test");
},
handlePosterClick: function(choc){
alert("ckciked")
window.top.$(".2l-body").css("overflow","hidden");
$("#cook").append(`<div style="background-color:blue;height:200px; width:300px" onclick="document.querySelector('#popover-div').remove();addScrollBack();>test</div>`);
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div id="cook">
</div>
<button v-on:click="handlePosterClick(choc)">
Book
</button>
</div>
Look at this :
https://codepen.io/hl037/pen/QWOjwyK
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
{{displayDiv}}
<div id="cook">
<div
v-if="displayDiv"
style="background-color:blue;height:200px; width:300px"
v-on:click="onDivClicked"
>
test
</div>
</div>
<button v-on:click="displayDiv=true">
Book
</button>
</div>
new Vue({
el: "#app",
data: {
displayDiv:false,
chocs: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true },
],
},
methods: {
onDivClicked(){
/*document.querySelector('#popoverdiv').remove();*/
this.addScrollBack();
},
addScrollBack: function(){
alert("test");
},
handlePosterClick: function(choc){
},
}
})
...Instead of manipulating the dom yourself, just use vue's template, with a model controlling its behavior. The same applies to your other component (the popup) : it should instead listen on a custom event on this component to add/remove scroll using reactivity.
Using vanilla javascript for dom modification, event-handling etc. is NOT recommended with vue. Always use vue's way of doing it. vanilla dom modification should only be done by experts, mostly to interface with non-vue code.
Not clear, but suggestion is use v-html instead of append
new Vue({
el: "#app",
data: {
cook: "Old content OR blank",
chocs: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
]
},
methods: {
addScrollBack: function(){
alert("test");
},
handlePosterClick: function(choc){
//alert("ckciked " + choc)
// window.top.$(".2l-body").css("overflow","hidden");
// inline Scripting not recommanded,
this.cook= `<div style="background-color:blue;height:200px; width:300px" >test</div>`;
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div id="cook" v-html="cook">
</div>
<button v-on:click="handlePosterClick('choc')">
Book
</button>
</div>

how can i add object in array which is in object as property (react.js )

first off, sorry for the confusing title. I couldn't find a way to say this more clearly.
These days, I'm working on my own project and face a problem. If you can give me some
advice, it would be a huge help for me.
So, this is my State
const[state, setState] = useState({
externalEvents: [
{ title: "Art 1", color: "#0097a7", id: 34432, custom: "fdsfdsfds" },
{ title: "Art 2", color: "#f44336", id: 323232 },
{ title: "Art 3", color: "#f57f17", id: 1111 },
{ title: "Art 4", color: "#90a4ae", id: 432432 },
]
});
and this is my input tags and function
<form className="todoinput" onSubmit={addTodo} >
<input type="text" value={title} onChange={e=>setTitle(e.target.value)} placeholder="Add event" />
<input type="text" value={custom} onChange={e=>setCustom(e.target.value)} placeholder="detail" />
<select>
<option value={()=>{setColor('blue')}}>blue</option>
<option value={()=>{setColor('orange')}}>orange</option>
<option value={()=>{setColor('green')}}>green</option>
<option value={()=>{setColor('purple')}}>purple</option>
</select>
<button type="submit">Add todo</button>
</form>
const addTodo = (e) =>{
e.preventDefault();
setState([...state.externalEvents,{title:{title}, color: {color}, custom: {custom}}])
setTitle('')
setCustom('')
}
This is what I wanted to make: I type title,custom and select color in input and select tags. And I submit it, then function is going to add new object in externalEvents(array)
I used spread to do this, but somehow it didn't work and console says "TypeError: Cannot read property 'map' of undefined"
<div id="external-events">
{state.externalEvents.map((event) => (
<div
className="fc-event"
title={event.title}
data-id={event.id}
data-color={event.color}
data-custom={event.custom}
key={event.id}
style={{
backgroundColor: event.color,
borderColor: event.color,
cursor: "pointer"
}}
>{event.title}</div>
))}
</div>
this is a part where map() happen, I think the reason map couldn't read property is because
I failed to send proper property to externalEvents.
thanks for reading, and your help will be appreciated.
p.s I used FullCalendar library!
When you initialized your state, it was an object with a key externalEvents which is an array
useState({
externalEvents: [
{ title: "Art 1", color: "#0097a7", id: 34432, custom: "fdsfdsfds" },
{ title: "Art 2", color: "#f44336", id: 323232 },
{ title: "Art 3", color: "#f57f17", id: 1111 },
{ title: "Art 4", color: "#90a4ae", id: 432432 },
]
})
But when you update your state, it is an array
setState([...state.externalEvents,{title:{title}, color: {color}, custom: {custom}}])
So based on your initial state, setState should be as below
setState({
...state,
externalEvents: [
...state.externalEvents,
{title, color, custom}
]})
Do note that {title, color, custom} is probably what you want, instead of {title: {title}, xxxx
Your problem is probably inside of your addTodo function.
This function sets state to be an array. Following this, state.externalEvents no longer exists.
To test this, try console.log(state) after it has been set in addTodo function.
Based on your intent, here is a modification of your addTodo function that may solve your problem:
const addTodo = (e) =>{
e.preventDefault();
// Use previous state, and make sure to return an object with an 'externalEvents' key as the new state
setState((prevState) => {
const newEvent = {} // whatever your new event is
return { externalEvents: [...prevState.externalEvents, newEvent] }
})
setTitle('')
setCustom('')
}
Further improvement
Furthermore, you can make things more simple by directly having an externalEvents piece of state, to remove the need for a nested externalEvents property inside some other state object.
For example:
const [externalEvents, setExternalEvents] = useState([
{ title: "Art 1", color: "#0097a7", id: 34432, custom: "fdsfdsfds" },
{ title: "Art 2", color: "#f44336", id: 323232 },
{ title: "Art 3", color: "#f57f17", id: 1111 },
{ title: "Art 4", color: "#90a4ae", id: 432432 }
])
If you adopt this, you would need to update your addTodo function once again, specifically the state update step.
Your state update step will now look like this:
setExternalEvents((prevExternalEvents) => {
const newEvent = {} // whatever your new event is
return [...prevExternalEvents, newEvent]
})
See here for more:
Setting state based on the previous state: useState hook, setState function. Accessing previous state value
I think that the issue is that you defined state as an object, with the key externalEvents, which is an array. But when you are submitting the form, in the setState function, you are setting an array, not the original shape.
I recommend you to do it like this:
const [externalEvents, setExternalEvents] = useState([
{ title: "Art 1", color: "#0097a7", id: 34432, custom: "foo" },
{ title: "Art 2", color: "#f44336", id: 323232 },
{ title: "Art 3", color: "#f57f17", id: 1111 },
{ title: "Art 4", color: "#90a4ae", id: 432432 },
]);
And in the form:
const addTodo = (e) => {
...
setExternalEvents(prev => [...prev, {title, color, custom}])
...
}

how to build href in bootstrap-treeview?

I'm using bootstrap-treeview to display a tree-like view of my data. The initial and basic implementation is working but I need it to when I click the text value, i get redirected to the link.
The JS function that renders the tree is:
function initTree(treeData) {
$('#treeview_json').treeview({
data: treeData,
enableLinks: true
});
// collapses all nodes
$('#treeview_json').treeview('collapseAll', { silent: true });
}
The enableLinks: true node property renders the link. But I could not find any documentation or example on the href property.
Does the link has to be supplied with the data or can it be built by the javascript?
You pass href as node attribute (see https://github.com/jonmiles/bootstrap-treeview#node-properties), so it is supplied with the data:
var tree = [
{
text: "Parent 1",
nodes: [
{
text: "Child 1",
nodes: [
{
text: "Google",
href: "https://www.google.com"
},
{
text: "Twitter",
href: "https://www.twitter.com"
}
]
},
{
text: "Facebook",
href: "https://www.facebook.com"
}
]
}
];
Check this example: https://jsfiddle.net/beaver71/bvpncxko/
Remember you must have enableLinks:true
function initTree(treeData) {
$('#treeview_json').treeview({
data: treeData,
enableLinks: true,
});
}

How to read a multidimensionnal javascript object?

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.

Show results in an ordered way in html page

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;
}

Categories