Knockout.js before and after examples? - javascript

Im learning Knockout.js through online tutorials, and even though I understand them I dont fully see how it makes things easier.
For example even though I understand this http://jsfiddle.net/rniemeyer/LkqTU/
this.firstName = ko.observable(first);
i dont see how its a significant improvement over something like this http://jsfiddle.net/rniemeyer/LkqTU/
function updateBox2() { var x=document.getElementById("first1");
document.getElementById('full').innerText = x.value}
but that was of course an extremely basic example. (The code samples here arent too good, better to check out the jsfiddle).
So my question is, does anyone have code examples whereby the first code performs an action using regular javascript and the second does the same but this time using knockoutjs and clearly shows how its a big improvement?

Rather than trying to compare vanilla JavaScript with KnockoutJS, I would try to understand how data-binding pattern simplifies client development.
Do you imagine your UI automatically reacting to a model change, and viceversa? Do you imagine that by just configuring the whole bindings?
With data-binding, your JavaScript will rarely need to manipulate the DOM, because the proper KnockoutJS binding will handle a lot of things for you and without your intervention.
Thus, you concentrate your efforts on manipulating the model as response to UI changes (invoked by KnockoutJS). And the UI changes automatically when you change the model.
For example, if you bind an observable array called items to a view like this:
<ol data-bind="foreach: items">
<li data-bind="text: $data"></li>
</ol>
...and you want to show 3 items in your view, it's just about doing so:
viewModel.items.push("Hello");
viewModel.items.push("world");
viewModel.items.push("!");
KnockoutJS adds new <li /> elements to your ordered list because the UI reacts to the whole items array changes.
Now try to use your mind, be formless and be like water, and I'm pretty sure you should be able to compare what extra-work would be required without using data-binding, and how many code lines may you save in a real-world project using this approach!

Related

Polymer - Load different components dynamically

I'm a Polymer novice, but I guess what the answer will be...
Recently I came across with this issue: I got to loop through a collection of elements (using dom-repeat) and display its contents. But every element has a unique display and bindings, making it almost impossible to display each element dynamically. The ideal scenario would be to load a different component for each display type, but it looks like there is no easy way to achieve this.
Some options I have been thinking of were the following:
Using dom-if but it would add crap to my resulting HTML.
Is there a dom-switch? If it were something like that and didn't leave empty template tags (as it would do with dom-if) it would be nice.
It's possible to load a component dynamically? Using something like this: <[[item.type]] item-configuration=[[item.configuration]]></[[item.type]]>
Any other ideas? I would really appreciate any ideas or solutions or at least a workaround for my issue.
TL;DR; you can't
Polymer (and Web Components in general I guess) are best when used in a declarative way. Out-of-the-box your best solution is dynamically creating elements and adding to DOM or messy use of dom-if.
(potential) OPTION 1
I guess you could fairly easily implement a dom-switch element to work like
<template-switch switch="[[some.value]]">
<template-case case="10">
<element-one></element-one>
</template-case>
<template-case case="20">
<element-two></element-two>
</template>
<template-default>
<element-one></element-one>
</template-default>
</dom-switch>
I wrote this off the top of my head. There are multiple ways to implement such an element. A crucial decision is whether to use <template> internally or not. In this plunk I've implemented such element without templates but simply using content distribution.
OPTION 2
There is also Polymer.Templatizer.
Faced with a similar issue of choosing element to render dynamically I created this Plunk as a proof of concept.
As you see, you extend the <template> element with custom rules, which match against a model. You then bind the matched template's nodes with the model using Polymer.Templatizer.
Thanks to Templatizer, you don't have to pollute your actual element with conditionals and still get full binding functionality.
I'm working on a more feature-complete solution. If you're interested I could move it to a separate repository and publish.

javascript newbie: what's the right way to apply the same behavior to multiple elements?

I'm taking my first adventure with javascript, and totally without my bearings. I'd like to show a thumbnail that opens a modal with a larger view of the picture (and this is really the only front end fanciness I'll need, so I'm trying to keep it simple). I've copied this code from w3schools, which uses getElementById. It works great for the first image on the page but clicking subsequent images doesn't pop anything up. Reading around on stack overflow it sounds like that's because I'm matching on the id, but each element on the page will/should have a different id (which makes sense).
I saw a post here where the person made the ids unique by appending the element's id. I could do something like that, but I (a) wanted to check if that's kosher and (b) then obviously the id will no longer match, so is there some different attribute I would tack on to match up my HTML with my styles? This must be a common problem- what's the right way to apply the same behavior to multiple elements on a page? For example I can give them
thanks!
UPDATE: based on everyone's feedback below I've modified the code to use getElementByClassName instead of getElementById- see gist here: https://gist.github.com/dianekaplan/1602a7c0a1c1ec6aa103b61d6530ff15
If I'm reading the code correctly, then the important lines for me to change are from line 115 to line 116- (to set the image info based on ClassName, not id)- and replacing 'myImg' with popup' in the style lines 5 and 11, but clicking the first image no longer opens the modal, so I missed something. Anyone see what's wrong that I need for it to work?
You should use a class name (the same in all img) instead of ids and then use getElementsByClassName() to fetch all of them, instead of getElementsById() which gets only one (as ids must be unique).
Then, you should store the full size image's url somehow in order to fetch it regardless of which img was clicked. One way may be using data attributes.
Example:
<img src="thumb1.jpg" data-fullsize="full1.jpg" class="popup">
<img src="thumb2.jpg" data-fullsize="full2.jpg" class="popup">
<img src="thumb3.jpg" data-fullsize="full3.jpg" class="popup">
var elems=document.getElementsByClassName("popup");
for(var i=0;i<elems.length;i++) {
elems[i].onclick=function() {
var fullsize=this.dataset.fullsize;
//open de popup, fullsize has the clicked image url
}
}
Code not tested, for the idea only.
To answer your primary question ID's are "supposed to" [1] be unique so unless you came up with a convention such as a prefix or regex you couldn't easily use them to group elements together.
If you want to group together multiple elements you could use a class, instead, in which case instead of getElementById you'd use getElementsByClassName.
That being said I wouldn't recommend that either; using vanilla JavaScript can be very time-consuming to make a complex application. You will be tempted to merge the UI with all your functionality. This works great for smaller applications but it can become very unruly, particularly if you don't take steps to allow yourself to refactor in the future, in which case you'll be stuck with an application few can easily be trained on and modify.
You are correct to learn the language, though, prior to a framework. JavaScript is especially quirky.
I would suggest if you're looking to create a web application to look into a modern JavaScript framework after learning JavaScript, HTML and CSS. (And focus on having a practice to being able to refactor/upgrade/improve otherwise you'll be stuck in 2016 and it'll be 2020 - you don't have to worry about this immediately, but start learning about how to do that while you're learning the language.)
To find frameworks I would suggest exploring what's out there. Here's an example of one on GitHub. That's probably a hand-coded list. It's also good to explore exhaustive lists, such as just looking at the "most starred" Repositories on GitHub that are written in JavaScript. And of course check elsewhere besides GitHub, too.
I happen to know AngularJS the best and it happens to be one of the most popular but I would recommend for you to explore and find one that has syntax you like. You might find a different one more intuitive. Here's a plunker that shows how to solve that problem in AngularJS.
Notice how all the functionality is separate from the UI and how declarative it is - the main directive has no idea how the images are being rendered - it just says here are some image url's and descriptions:
scope.images = [{
url: 'http://www.w3schools.com/howto/img_fjords.jpg',
description: 'Trolltunga, Norway'
},{
url: 'http://www.w3schools.com/howto/img_fjords.jpg',
description: 'Other Description'
},{
url: 'http://www.w3schools.com/howto/img_fjords.jpg',
description: 'Another Description'
}];
This is what initializes the app: <html ng-app="plunker"> and <main></main> is akin to the "main method" in that it is the component that calls all the other components.
It's much easier to test an app's functionality if you're careful to separate out the presentation concerns from the rest of the app. It will take a while to learn JavaScript and probably any framework, though, so don't expect too much too soon if you're just getting your hands wet in JavaScript - but if you've programmed for a while you already know this :)
(Disclaimer: What I did isn't necessarily the "best practices" as I tried to simplify it a bit so as to not overwhelm OP too much with information, although the added complexity is useful in more advanced scenarios.)
[1] "Supposed to" meaning browsers may do their best to render a page, even it isn't "compliant" HTML. Web Applications suffer from having to have the same code work on different browsers, operating systems and versions of each all implementing the standards (or choosing not to) differently. It's a nightmare if you haven't ran into it, yet.

Web Page Javascript Objects

newbie question.
I've read some of the W3Schools, I also read a lot from other sources on the internet, however I can't find what I need, and I'm sure it's quite simple to you.
I'm using ASP.Net, and I want to add to my website, multiple items, which every item hold a picture, and some other information, including links. I'm pretty sure I don't need to write the code for every item in the HTML source, and I don't know exactly how to implement my this.
The basic idea is that my items will be imported from a Database that I create in visual studio, and I want to style my webpage so they would appear in a certain formation, I thought I might need to use Javascript or CSS for this, hope I'm not mistaken.
Javascript isn't some sort of magician that will render all your stuff on its own. However, you can use it to attach a template to every of your items.
What you have to do is :
Create a base HTML template for 1 of your item that can be applied to all of them
Create a Javascript function that will attach thoses CSS classes and HTML attributes to every element out of your DB (or you could use a templating frameork .. since there's a lot of them I'll let you look for it on Google. It's pretty easy to use)
On page load or whatever event you want to bind on, you call your function which will attach the CSS and HTML to every element out of your DB and will render it on your page
Enjoy what you've done.
I hope this helps. Good luck ! ;)

Refactor a huge form with a Javascript Framework

I have a huge form divided into sections. It has about eight sections and it will simply be unwieldy to put this giant form on one page. No one would ever slog through it.
I also decided that dividing it into pages will also not be ideal because if someone is section 6 and realizes he needs to change something on section 2.
I created a client side solution using Jquery. So You just click tabs representing sections of the form. So you hide a previous section section when you click on a new section and handle all the logic of saving server side making sure someone can switch back and forth while validating data on each section. Behind the scenes its still one huge form. A lot of Jquery is used to make it work properly. It is tightly coupled to the DOM and no one can understand the code unless I explain.
Also when making changes you have to make sure there are no lingering events which cause something unexpected to affect another section of the code.
Its quickly becoming a monster. I think this is an ideal problem a Javascript framework would solve but I have no idea where to start. How would it fit in the context of Javascript MVC especially all the DOM manipulation and event driven approach I use. any ideas or suggestions are welcome.
I would consider using AngularJS
This is a real war story - I was struggling with the exact same issue you are. Huge unwieldy form, needed it to be refactored into re-usable components(since one portion of the form included a pricing page).
Getting started is pretty easy, I'd suggest to look at the tutorial before you see my solution.
Here's how I solved my issue -
Have one controller for your form.
Use UI-router for making sub-routes of your form (e.g. /signup/profile, /signup/address etc); all of them being controlled by your main controller. Store them in separate HTML files as templates being rendered on a view (yay!)
Also, you don't need a major commitment to use angular, you can just use it for this purpose in your app.
Hope this helps.
Frameworks that handle data binding and embedded control statements sound like they would be ideal for an issue like this, like Knockout.js or Angular.js.
For example, with knockout, you could have a segment like:
<div data-bind="if: someCondition">
Only show this section of the form if the condition is met
....
</div>

javascript templating engine that maintains focus on textboxes etc?

So I know there is a few templating engines out there, but I thought I'd ask for someones experience and reccomendation on one that can do what I'm after.
I'd previously made an (intranet) web app that used asp.net editable listviews to take input and used an update panel to make it persist the data regularly (save)
This worked ok but was alot of hackery to get focus to maintain on the ajax postback amongst other things. This is because update panels rewrite the whole section of html on each ajax postback.
So I figured for some more control and a better user experience (and quicker speeds) I'd try a jquery/javascript based templating engine. What i'm doing is making a sort of to do list (its more than that but lets just keep it simple for this example) where someoen fills out a line with an action, due date, and some other fields.
I liked John Resigs Microtemplating engine so I used that. However after working it all out it seems that it re-writes the whole javascript template each time it updates, which is just what I was trying to avoid, as it loses the users focus. I was hoping for something that would just append things onto the end - why do they need to rewrite everything?? I could do as I did with the udpate panel and use some hacking based on the current focus but I would rather avoid this and make it seamless.
am I going to have to manually code this up, or is there a decent way of doing it out there?
Resig's Microtemplating is great. However, like most client-side templating engines all it gives you is a string. How you get that string into the DOM is up to you.
Why do they need to rewrite everything?
The templating engine is not overwriting anything. Rather that is being done by you (however it is you are putting it into the DOM). For example:
var template = Template('template_id');
// The template engine simply generates a string:
var generatedHtml = template({data:'goes here'});
// The engine's work is done at this point.
// Now lets get the string into the DOM:
myElement.innerHTML = generatedHtml; // OVERWRITES
I was hoping for something that would just append things onto the end
Since you are using jQuery it is trivial to append rather than overwrite. Instead of the innerHTML line above you would use jQuery's append method:
$(myElement).append(generatedHtml);
Now, regarding your focus problem, again this is not strictly due to the template engine but rather the nature of DOM manipulation in general. The solution is to force the element you need to have focus to focus:
Lets say your template looked like this, in Resig's microtemplating parlance:
<script type="text/html" id="template_id">
Foo: <input type="text" value="<%= data %>" />
</script>
Continuing the JavaScript example of prior, you focus like this:
$(myElement).append(generatedHtml);
// Focus the just inserted text box:
$(myElement).find('input').focus();

Categories

Resources