I'm creating a form on a web page, but I want that form to change as a user inputs values.
Example: If we have a drop down menu: ObjectType
And someone chooses Cars when that selected I'd want new options below to show up. Say, Make, Model, Year, & Notes.
Whereas, if that person chooses Vegetables then maybe all I want is a checkbox for Root Vegetables.
My question is what is the best way to do this. My form is pretty intricate and is going to have perhaps 20 different possible set ups, but I want those set ups to be sorted. I used appendChild() with AJAX requests, but I just ended up with out of order fields. And on top of that, the occasional slow connection keeps an individual waiting for a field to show up.
Rather than loading HTML pages with these form objects (technically part of a table), should I be keeping all of this stuff in an array? Is it possible to just load one HTML page or XML object and use selectElementById() on that result after it has been saved?
The objects I'm loading are rows, here's an example of one and what it would need to be able to do:
<td>
<strong>Abilities:</strong>
</td>
<td>
<textarea
id ='abilities'
name="abilities"
style="width:100%" rows="4"
onchange='userCreation.updateAbilities()'
onkeyup='userCreation.updateAbilities()'>
</textarea>
</td>
I have a table in my page, I was creating a new tr element with JavaScript, setting this as the innerHTML and then appending the child. Is there a better way to do this?
I would just put all of the form elements in a page, and hide the ones you're not using with CSS. That way you maintain order, and don't have to wait for fields to show up. It will slightly slow down page load time, but make your life a lot simpler.
Otherwise, I'd store the name (or whatever) of each field in an array or object, and when it comes time to AJAX load it, look up its position first and put it there.
Just have the entire for in the page and just change the visibility of different sections, based on user interaction instead of dynamically loading elements via AJAX.
Related
I'm currently stuck with how to implement something into a database. I need multiple values to be carried over to a general page. To explain more in depth, let me tell you what I have done, and where I'm stuck.
I'm creating a New General Page form. I have a special offer form box generator, which upon pressing a button creates a new form consisting of six fields. For each new page, you can generate an infinite amount of offers. The problem I'd face if I give each offer an ID which gets imported to the general page is that it might either take ID=1 for one page and ID=2 for another page, or ID=1 and ID=2 will both be one every new page generated. What I need to do is get, for example, 4 offers for one page sent to the database, and when the New Page is generated it'll have the four offers called. How would I go about creating a database for them?
Momentarily my table for it looks as such:
||idOffer||price||idDays||idPersonQuant||offerInfo
where ID Days and ID Person Quantity is unique to the individual offer.
I know I have to get all of the offers under one ID which will be unique to every page, but how do I get various amounts of offers under one ID?
For those who want to get a look at the script, here it is: JSFiddle
It works, but not on JS Fiddle.
If there is any confusion, I will post a JSFiddle with my code for the entire form and how it's going to post stuff.
Thanks in advance! Been stuck on this for ages :/
If you want multiple "offers" under one ID, you can create a new table called offerGroup (or similar). Entries in this table will correspond to one "page", so when a new page is created, there should also be an associated offerGroup. The table wouldn't need to be complicated at all, just a primary key:
||idGroup
In the "offer" table, you can then reference the id of the group that the offer belongs to.
||idOffer||price||idDays||idPersonQuant||offerInfo||**idGroup**
This solves your problem where you might have anywhere from one to infinity offers on one page. I hope I understood your question correctly.
I'm writing a web application that displays a large number of rows of data (~2000 at present), each of which has a drop-down "select" element with ~100 options. Any of those options can be selected by default. I'm generating all the actual DOM elements client-side. My problem: rendering this beast takes ~4 seconds on my relatively recent machine, which is really suboptimal. I know the problem is specifically with all the select elements, because replacing them with a bit of static text or a single-option list causes render time to be nigh imperceptible.
The vanilla code, minus failed experiments (see below) is here.
Avoiding the suggestions of "paginate your data" and "don't have so many options in a select", what is the most efficient way I can write my append / render code, assuming I do have a legitimate reason to display that much data and have that many options? For my purposes, Firefox is the only platform I care about.
Things I have tried:
Using an async loop to append rows to the table (slower than a regular loop, and oddly didn't render the intermediate results)
Building up a string that represents the body of the table and inserting it into the DOM in a single call (almost identical performance)
Instead of inserting the entire options list, inserting a single-option "select" element, and then populating the entire list when the "select" element gains focus (presumably because someone is trying to change it). This was actually pretty high-performing for the initial render, but then populating the element with the full list caused some weird behavior, losing focus and never actually being able to "open" the select element.
Right now my default assumption is that the third option is the way to go, and I need to figure out how to do some bookkeeping about what has already been populated. But my suspicion is that there is a plainly better / faster / more idiomatic way to do this. Is there?
Yes, I would "lazily" generate and/or populate the dropdowns.
That is, only create and populate the dropdowns when the user clicks on them, as probably almost all of the dropdowns in the 2000 rows will never be used right?
Perhaps a select element might not be the best UI here too, but instead some kind of HTML menu like so: https://jqueryui.com/menu/ that is created, populated and displayed only when the user clicks on some kind of button to display it.
I've a question about best practices in javascript.
I've a dropdown menu with some statuts. If the statut is : external, I want to display a form. I don't know the best way to do this. Do i need to hide a DIV from the DOM and display him when i need it or do i need to generate my form dynamically in jquery and make a call ajax to populate some data.
It really depends on your application. If you already have a lot of elements in the DOM, and the likelyhood of actually needing to show this form is low, you may want to add it later (using ajax) because in most cases you don't need it anyway. However, if your DOM load is light, and in most cases the form will be shown, you make want to have it ready and hidden so that is can be quickly shown.
There is also a middle ground where you can "lazy load" it (using javascript on page load), and keep it in a json object until it is ready to be used. This will keep your DOM responsive, and give the added benefit of a quicker load of the form.
it depends on the probability of user clicking on that element and number of elements already present in the DOM. I suggest to create form runtime whenever user performs action instead of hiding it. There are some browser plugins which shows all hidden elements in a page.
Unless your page is unusually large already or there are a lot of different forms like this that could be used from the same page, putting the HTML into the page and just starting out with it hidden gives you the advantage that all your markup is in one place (in the HTML file that represents your page) and can more easily be centrally maintained that way.
When you start putting markup into your javascript, you split up the maintenance of the markup between both the HTML of the page and the HTML that is embedded into your page.
If, on the other hand, you had a lot of these forms that were all slightly different that could all be used from the same page, then it gets messy to pre-specify all possible combinations of the form in the original HTML and you would probably be better off dynamically generating it via javascript or perhaps generating it from a template with slight modifications.
A little web design dilemma: I have a form with a lot of options, mainly radio buttons but not only.
I want the form to open up gradually, meaning at the beginning only two radio buttons are visible, and after the user picks one, more options appear under the chosen radio button. If the user then switches the pick, the page updates and shows the options under the new pick.
This happens on several levels, say 4 or 5 levels, and at the end there is a submit button that submits only certain inputs according to the branches the user chose. Also some of the branches have identical components even though the initial choice was different.
These are the options I could think of:
Build the complete form in the html body and use jquery to hide and show them according to the choices of the user. This means I have to write sections that repeat themselves twice.
Write nothing in the body, and append new elements when the user makes certain choices. This means the JavaScript is more complicated, because I have to make sure nothing appends twice.
Write an HTML skeleton of the form, and use append to fill it. Then use jquery to show and hide elements. This has none of the disadvantages but seems a bit unaesthetic.
Which one should I pick? Any better ideas?
It really comes down to your knowledge of javascript. The cleanest way would be to append to form using javascript. This way you can avoid having duplicates in your form.
If you are not that familiar with javascript and don't know how to append the form, then I would use javascript to show/hide the different parts of the form.
I think using javascript to append would be the correct way, but I don't see anything really wrong with using javascript to just hide parts of the form.
Probably going to use http://wiki.jqueryui.com/w/page/12137997/Menu
or JStree (http://www.jstree.com/) which I found out about from here http://wiki.jqueryui.com/w/page/12138128/Tree
I am creating a dynamic table control with ASP.NET/C# and the table is being used to hold a form. I need to allow users to click on a button in a row and make a duplicate of that row right below the original. My page is also using AJAX and jQuery.
I have tried to use Table.Rows.AddAt(indexoforigrow+1, newrow) but I get an error that the index is out of the range of values. I figured maybe I wasn't getting the original row's index correctly so I just tossed in a 1 and still got the error.
I also noticed that when I press the button to execute the code, the table disappears. Any ideas on how to fix that?
I am thinking that if I am unable to get these issues fixed I will have to loop through the table and submit the data to a temp table, adding a new row where indicated. Then I would pull all of the data back out and display again.
EDIT
I moved on when I could not get this working and tried to setup my submit functions to loop through the data and submit it to a db and realized that I am experiencing the same issues when clicking the submit button as when I click the add row button. It appears that my issue is really with viewstates/postback.
I did some reading on this and from what I can tell the solution is to re-create the dynamic control on page load every time. But I am confused about how I can do this if I have no idea how many rows/cells I have and how is the information the user entered kept in the form? I have no way of saving the information to a DB or anything because as soon as submit is clicked it all disappears.
Have you considered using a different control? One of the grid controls might better serve your purpose.
I've handled situations (that sound) similar to what you're describing by using the footer of a GridView (among other ways). The big trick is to bind the display object (Table, GridView, etc.) to a list of objects. Then you manipulate the list of objects, rebinding the display object after the list has changed.
You will need to persist this list in some manner, or you could wind up with the list being reset to null. One way would be to save it as part of the session.
At any rate, the idea is to have a display object (GridView) bound to a list of objects. When the user clicks 'add', an item is added to the list. Save the list, then call the GridView.DataBind method.
You are on the right track with re-creating the dynamic table each time the page loads. I have dome similar things and my solution was to keep a client state in a hidden field on the page. Every time you add a row to the table on the client, increment a counter or adjust the state data in the hidden field. Then, on the server-when the page posts back, read from that hidden field to know how many rows were added on the client. You will have to use some kind of naming convention for the new rows you add(and the widgets in them) so you can re-create them on the server.
A simpler option may be to use an UpdatePanel. Rather than try to add the rows on the client, your "add row" button would cause a partial update. The server side code would add the new row to the table and the viewstate would be updated.
I ended getting my data guy to do a bit more processing on his end so that I could just bind a ListView to a sproc. Solved a few of my problems.
Thanks for the helpful comments.
Just returning to this almost a year later because I faced a similar issue in my current project. I was doing a few things wrong my first time around. First, I did indeed need to recreate the controls every load, but I also had to create them earlier in the page cycle. I was trying to create them during page load, which is after the viewstate is loaded.
The controls need to be recreated with the same ID before viewstate is loaded. I went with page init and it worked fine.