underscore js - renumber template rendered element attributes - javascript

I've got an form with the ability to have an infinite number of user-added inputs.
As an example, imagine a job application with an "add references" section. There's a "+" button, as well as an "Remove" next to any already added reference.
Here's an example template
<script type="text/template" id="referenceTmpl">
<div>
<h2>Reference No. <%= index %></h2><a id="removeRef<%= index %>">Remove</a>
Name: <input type="text" name="references[<%= index %>].name" />
Email: <input type="text" name="references[<%= index %>].email" />
(...)
</div>
</script>
When any "reference" is removed, I'd like to renumber the others. As the form inputs may already contain unsaved data, I need to do so without fully re-rendering the template. I'd like to do this in a salable way (one that doesn't require too much extra code per input) as the solution may be used in a more complex application.
Feel free to assume I'm using jQuery if the solution could benefit from it.
Any ideas?

The best way to do this kind of thing without hacking into the code, is to use a model(list) for your so called "references".
You should try Backbone.js in combination with Underscore.js:
Backbone.js documentation
There is an TODO example application that does exactly what you want:
Application code-breakdown
Example application
It might take some time to set up, but when you are finished, you will get work done much quicker.

Related

Angular with ng-flow : existing flow object

Might be a silly question but I couldn't figure the solution out myself or google it. I'm using a button for click+upload files. However, I also want to add the drag+drop functionality the same time - using preferably the same flow object and function. Here's my current code:
<div flow-init flow-name="uploader.flow" flow-files-submitted="uploadFiles()"
flow-file-success="fileUploaded()">
<label for="file-upload" class="upload">Files</label>
<input id="file-upload" type="file" flow-btn>
So I'd like to use the 'uploader.flow' scope for my drag and drop too executing 'uploadFiles()' with it on submit. Here's what I've been trying:
<div flow-init flow-object="...??..." flow-drop
flow-files-submitted="uploadFiles()" flow-file-success="fileUploaded()" ></div>
I believe myself the issue is only that I can't figure out what to put in flow-object. But I doubt it was that simple. Might be something also with the new init? Should it be done or not.
Another way around of course could be to find the first shared parent element and init it there instead for both the same time? But would this be a bit too vague?
So in the end I did what I didn't originally want to do. I went up the parent elements until I found a common one the both were children of and did the initialization for ng-flow there instead.
It works.

Fill forms in JavaScript

I'm currently a student in Software Engineering, and I'm trying to create a small program (I don't know if the word "macro" is appropriate for it) in HTML or JavaScript, to fill a form from a webpage.
The webpage has the following code, placed in the head section:
input type=password name=code size=8 maxlength=8
input type=password name=nip size=8 maxlength=8
input type=password name=naissance size=8 maxlength=8
I've been thinking of maybe using JQuery, as I've browsed a little bit on the internet to figure out how to do it, but I don't really know how to do that. I'm pretty sure the only way to do it is to modify the values of the fields "code", "nip" and "naissance", but how do I get access to them from an external file?
Please note that I have bases in HTML and JavaScript, but nothing amazing - I'm still learning :/
Since you're looking to use jQuery, this might be a good place to start:
http://api.jquery.com/attribute-equals-selector/
Next might be a good tutorial in jQuery to get you started. I'm going to assume you can find those on your own, and I'm going to jumpstart your work:
var selector = 'input[name="code"]'; // <-- we define the element we want to find here
// we will use that to select a jQuery element like this --> $(selector)
$(selector).val('CODE!!'); // <-- it's just that easy to set a value.
So if that's what it takes to set the value for code from javascript, you can guess what the other two would look like. I'll give you a hint on the second one:
$('input[name="nip"]').val('NIP!!');
Of course, all this assumes you do use jQuery in the browser to accomplish this
I believe what you are looking for is simply accessing the fields from javascript. You can include any external javascript on the HTML page:
<html>
<head>
<script src="http://someexternalurl.com/js/jsfile.js" type="text/javascript"></script>
...
Then in this javascript file you can access the elements as:
alert(document.getElementByName("nip").value);
document.getElementByName("nip").value = "abc";
Hope that helps.
You can accomplish you project by going through this links
w3school
tizag
jqueryui
jquery
Go through this links
with regards
Wazzy

JQuery parameter injection on bind/click vs. embedded click handlers with parameters

So the old JavaScript aficionado and the young jQuery wizard in me are having a little disagreement. Sorry for the long setup, but the heart of the issue is whether to embed onClick code directly in my HTML or to go jQuery-style and and use bind() or click(). I find myself & myself disagreeing on this topic quite often, so I thought I would try generate some discussion on the issue. To explain the issue, the pattern below seems to bring this to the forefront most often.
Typical Example
I'm writing a search for a member directory. On my interface I have various filter criteria like "gender", "member since", and "has profile photo". A criteria looks like this ...
A user can select an option by clicking on the text (e.g. "Female") or choosing the radio button.
When a selection is made the appropriate radio button is selected the text is bold-ed
My html ends up looking something like ...
<div id="FilterContainer_GenderDIV">
<span id="FilterLabel_Gender">Gender:</span>
<span id="FilterSelection_Gender">Any</span>
<span id="FilterChicklet_Gender" class="sprite_MediumArrowDown inline" ></span>
<div id="FilterOptions_GenderDIV">
<input type="radio" id="GenderID" name="GenderID" value="1"/> <a href="" id="FilterOptionLink_CoupleGender_1" >Male</a><br />
<input type="radio" id="GenderID" name="GenderID" value="2"/> <a href="" id="FilterOptionLink_CoupleGender_2" >Female</a><br />
<input type="radio" id="GenderID" name="GenderID" value="0" checked="checked"/> <a href="" id="FilterOptionLink_CoupleGender_0" class="SearchSelectedChoice" >Any</a><br />
</div>
The issue really arises when a user clicks on the text link. At that point I need to know which radio set to change,which link text to bold, and take the newly selected text and change my header label. I see a few options for making this type of scenario work.
Options for making it work
jQuery Injection with Clever element names
I can use jQuery to bind to my elements in a generic fashion. $('#FinderBodyDIV input:radio').click(SearchOption_Click); Then sort out the appropriate ID & text with clever dom inspection. For example, name my hyperlink could be named GenderID_Link_1 where 1 is the ID I should select and GenderID tells me which radio set to change. I could use a combination of '.parents().find()and.siblings()` to find the radio next door and set it with the ID.
This is good because my binding code is simple and my jQuery is separated from my HTML
It's bad because my code functioning now really depends on a brittle HTML structure & naming.
Bind elements individually with eventData
An alternate option is to gather up my set of elements and for each individual element do a 'bind()' passing eventData.
var elements = $('#FinderBodyDIV input:radio');
elements.each ( FunctionWithLogicToBindPassingEventData );
This is satisfying because I've separate the logic for binding event data from a brittle HTML structure.
It's bad because I've simply moved the brittle piece to a new function
It's also bad because I've introduced slowed down (relatively) the binding (more DOM traversal).
Embed onClick code in the HTML
This is where my old JavaScript inclinations keep taking me. Instead of using jQuery to inject bindings, I change my link/radio button HTML to include click handlers. Something like ...
<input type="radio" id="GenderID" name="GenderID" value="1" onClick="SetGender(1,'Male')"/> Male<br />
This is satisfying because i know the values when I'm generating the HTML, so I've simplified my life.
I've removed a lot of dependency on my HTML structure (although not all).
On the down side, I've co-mingled my JS and HTML.
It feels dirty.
So what's a boy to do?
This seems like a fairly common scenario. I find it pops up in quite a few situations besides the one I've described above. I've searched tubes on the interweb, blogumentation, and technical articles on twitter. Yet, I don't see anyone talking about this issue. Maybe I just don't know how to phrase the issue. Whatever the reason, I don't feel good about any of the solutions I've come up with.
It really comes down to how do I associate a clicked element with it's related data--JSON, embedded in HTML names, or otherwise. So what's your take?
The pat answer is that embedding the onClick call in the input element goes against the unobtrusive javascript concept. However, I'm the kind of developer that'll go ahead and use it anyway if it gets the jorb done and the audience is not likely to have javascript disabled.
If I'm understanding the problem correctly, you need a way to do things jQuery-style without relying on html structure and such. Give your radio buttons a class name, for example, the "Male" radio button can have class="Male", and you can select it via jQuery easier.
Bonus: There are some instances where you may need to assign some element more than one class, for example, you are filtering by language and by country. So you can assign some element multiple classes like this:
$('#someElement').addClass('French').addClass('fr-FR');
And select it using either class later.

Html Helpers generates ID from model properties. How do I target 1 particular element with JavaScript and CSS if many elements have the same ID?

As it's recommended, Javascript must be kept in a physically separate file (to be unobtrusive). So how do I access a particular element in particular page? should I detect those elements by id? that would mean 2 elements can't have the same id even if they are not located in the same page.
Well, for instance, using the Html helpers methods generates element's name + id from the model's properties. If I use the same model in several pages, many elements will have the same id. How can I target them in different pages. By the way, CSS work the same way.
EDIT
Let's say I've this
<% = Html.TextBoxFor(x => x.FirstName)%>
It will generates
<input type = "Text" name = "FirstName" id = "FirstName"/>
Let's say I've this textbox in 2 differen pages. If want, for instance, to disable the textbox located in page A, how do I do it knowing they are two of them in 2 different pages. How do I discriminate them from my external javascript file?
Thanks for helping
I suggest that for each page the uses the same model, you create a wrapper div
<div class="pageA">
// the model stuff here
<% = Html.TextBoxFor(x => x.FirstName)%>
</div>
<div class="pageB">
// the model stuff here
<% = Html.TextBoxFor(x => x.FirstName)%>
</div>
and then use Jquery selectors to get the correct element $(".pageA input[name='FirstName']") (not sure if this syntax is correct).
You cannot have multiple elements on the page with the same id. That isn't valid HTML.
So when you use the same HTML helper multiple times, you need to pass different names:
<%: Html.TextBox("Foo", Model.Foo) %>
<%: Html.TextBox("Bar", Model.Bar) %>
Correct me if i'm wrong, but are you saying, you have some elements with the same id, on multiple pages, that you want to attach different behaviour to? If so then this could help you out. if not, then what Craig said.
You can use more specific selectors, or give your selectors context
have a look at the documentations here: http://api.jquery.com/jQuery/
under this header:
jQuery( selector, [ context ] )
it explains a bit about selects and context. you should be able to use this and some creative page building to target the right element with your jQuery.
So you have two files, each with a text field with the id "FirstName". When you're script runs on Page A you want to disable the field, but not when your script runs on Page B.
Is the structure of the two pages identical? I suspect not if you're handling these fields differently. Use the context to your advantage. Like if the one on Page A is in a div with id "thisDiv" and the other is in a div with id "thatDiv" you could document.getElementById('thisDiv'). If you get an element then disable the field, if not do nothing.
If you want a more specific answer you're going to have to give us more context.
Well JavaScript may be kept in a separate file or not, but it is definitely included as part of the HTML send to the browser for a particular page. I Hope I've understood your question, but, generally if you have you JavaScript code in a file, lets say utils.js then in your html generated should include (probably within the <head> tag):
<script type="text/javascript" src="/path/to/utils.js"></script>
The script get included in the page, and when the browser encounters this, it loads and then runs the script, for that page. Therefore, it is not important what the ids for elements on different pages are.
Does that make sense, or have I completely misunderstood your question?
Update:
Ok, so based on your comments, I think I understand. You have
//Page 1
//When loaded, this input should flash blue via javascript for example
<input id="firstName" .../>
And
//Page 2
//When loaded, this input has some other fancy effect/behaviour
<input id="firstName" .../>
Well in this case, as far as I see, there are only 2 types of answers. Have two seperate external js files, one per page and this way you can change to your hearts content ...OR... have some sort of hidden field in your page that tells your script what page it is looking at (this seems hacky)
<input type="hidden" value="page1"/> //etc..

Updating HTML via JSON/AJAX

I've been using JSON to handle AJAX functionality in my rails applications ever since I heard about it, because using RJS/rendering HTML "felt" wrong because it violated MVC. The first AJAX-heavy project I worked on ended up with 20-30 controller actions tied directly to specific UI-behaviors and my view code spread over controller actions, partials and rjs files. Using JSON allows you to keep view specific code in the view, and only talk to view agnostic/RESTful controller actions via AJAX to get needed data.
The one headache I've found from using pure JSON is that you have to 'render' HTML via JS, which in the case of AJAX that has to update DOM-heavy elements, can be a real pain. I end up with long string building code like
// ...ajax
success: function(records){
$(records).each(function(record){
var html = ('<div id="blah">' + record.attr +
etc +
')
})
}
where etc is 10-15 lines of dynamically constructing HTML based on record data. Besides of the annoyance, a more serious draw back to this approach is the duplication of the HTML structure (in the template and in the JS).* Is there a better practice for this approach?
(My motivation for finally reaching out is I am now tasked with updating HTML so complex it required two nested loops of Ruby code to render in the first place. Duplicating that in Javascript seems insane.)
One thing I've considered is loading static partial files directly from the file system, but this seems a bit much.
I like the idea of templating. In my experience it can really clean up that messy string manipulation!
There are many solutions, for example, check out John Resig's (creator of jQuery):
http://ejohn.org/blog/javascript-micro-templating/
I would go with creating an HTML structure that contains placeholders for the elements you'll need to update via AJAX. How much structure it applies will depend on what you're updating; if you know the number of elements you'll have ahead of time, it would be something to the effect of
<div id="article1">
<div id="article1Headline"></div>
<div id="article1Copy"></div>
<div id="article1AuthorInfo"></div>
</div>
<div id="article2">
<div id="article2Headline"></div>
<div id="article2Copy"></div>
<div id="article2AuthorInfo"></div>
</div>
You then write code that references the id of each element directly, and inserts into the .innerHTML property (or whatever syntactically more sugary way jquery has of doing same thing). IMHO, it's not really so terrible to have to assign the contents of each element, the part that you don't want to have to sprinkle through your AJAX functions is the HTML structure itself; in your app the content is volatile anyway.
However, it looks like you might have a list of an unknown number of elements, in that case it may be that you'd need to just put in a placeholder:
<div id="articleList"></div>
In that case I don't really see a way to avoid building the HTML structure in the javascript calls, but a reasonable amount of decomposition of your javascript should help that:
function addArticle( headline, copy, authorInfo, i ){
createDiv( "article" + i + "Headline", headline );
createDiv( "article" + i + "Copy", copy);
createDiv( "article" + i + "AuthorInfo", authorInfo );
}
(not working code of course, but you get the idea,)
You could use the load function in jQuery;
This loads the content of a page into a div like this:
$('#content').load("content/" + this.href.split('#')[1] + ".html", '', checkResponse);
Just make a dynamic view and you are good to go...
Just happened to find exactly what I was looking for: Jaml

Categories