How to append additional sets of fields to html form - javascript

Example: let's say we have a form with 3 fields: pc, part_id, part_details. Sometimes you will want to add additional parts to database when adding pc, so part_id and part_details should be duplicated(part_id and part_details should be corresponding). What I want is the best way to append this two fields to the form?
I know if you just want to duplicate one field you can name the field like this:
<input type="text" name="part_id[]">
Then we can easily get the post data as array. But now we are duplicating more than one field, if we use the approach above at the post end the two/multiple arrays will not be relevant. The approach described here seems to be a good one http://www.quirksmode.org/dom/domform.html, but the fact that names are changing all the time makes it complicated to use the post data as well.
There is another possible approach described here Multiple Forms With Input Fields With The Same Name Attribute? Good Or Bad? . It gives an idea to duplicate the entire form. I am not sure if I understand it correctly, but when I try putting two identical forms in the same page and submit one of them, only data from this form will be submitted, the other one will be ignored. Also it is not suitable for my scenario as not all the fields should be duplicated.
So what is the best way to accomplish this duplicating job?

In the link you gave, they didn't duplicate the form, just the elements inside the form which is fine. If all you are adding is multiple parts to a single PC then there shouldn't be a problem. The parts will be linked via array indices (you can rely on the ordering).
The first instance of part_id[] will correspond to the first instance of part_details[]. This should be distinguishable in your server-side language. In PHP for instance, part_details[2] will correspond to part_id[2] etc.

You can use another level of indexing:
<input type="text" name="pc" />
<!-- First part -->
<input type="text" name="parts[0][part_id]" />
<input type="text" name="parts[0][part_details]" />
<!-- Duplicate part -->
<input type="text" name="parts[1][part_id]" />
<input type="text" name="parts[1][part_details]" />
<!-- Another duplicate part -->
<input type="text" name="parts[2][part_id]" />
<input type="text" name="parts[2][part_details]" />
The fields for each part (id and details) can be easily generated using jQuery.

Related

JS and/or D3 Methods of storing Dynamic User Inputs

My question is similar to the one posed here: storing user input in array
My use case is different in one crucial aspect, I do not have static inputs. At any one time, there could be anywhere from 1 to 3 user number inputs on my page. They are also removed dynamically too, so I can't just create them all, then style them as needed something like using display:hidden;.
My question is: What is a js solution that can store user inputs into an array robust to inputs that may or may not have been appended without an if clause for each array in the event the element hasn't been appended yet(!==null).
Or if d3 has a simpler approach than native javascript to store number inputs into an array, that would be an acceptable answer too. I postulated this selection: d3.selectAll('#input1,#input2,#input3') but I'm not sure if values can be retrieved and stored in an array from such a selection.
Here is a worked-out example:
The document could potentially have 3 inputs, but lets say the current state of the document only has 2 inputs with IDs: #input1 and #input2. So I need to store the values of the existing inputs, and a 0 for #input3 because it has not been created yet. I'm not sure how to create an array comprehension with these requirements. I was thinking something like:
my_array.push(d3.selectAll('#input1,#input2,#input3').each().value())
But like I said above, I want the array to contain the value for each input. push() would just add another item to the array. The array would exceed 3 values if the event listener was triggered more than 3 times, which is not what I want. I just want an array that is updated with the current values of all existing number inputs (and a value of 0 if input has not been appended yet).
Your question is not exactly clear, but it seems to me that you want to get all the values of the inputs, without knowing how many of them you have on the page.
If that's the case, you can simply use...
d3.selectAll("input[type=number]")
..., which will get all the inputs present on the page when you call the function.
Here is a demo, look at the console:
d3.select("button").on("click", function() {
var inputs = [];
d3.selectAll("input[type=number]").each(function() {
inputs.push(this.value);
})
console.log(inputs);
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="form">
<h1><b>Please enter data</b></h1>
<hr size="3" />
<br>
<label for="input 1">Input 1</label>
<input id="input1" type="number">
<br>
<label for="input 2">Input 2</label>
<input id="input2" type="number">
<br>
<label for="input 3">Input 3</label>
<input id="input3" type="text">
<br>
<hr>
</div>
<button>Submit</button>

Submitting multiple values for one input field

What I'm trying to do:
I'm trying to build a very simple visual layout builder.
The idea is that, the user selects a block, and it has some settings in it, those setting values are stored in the hidden input, and when the user saves the page, i store those values in the database.
Basic block is ok:
For example, user selects a 'text' block, it is added like this:
<div>
<input type="hidden" value="text" name="item_name[]">
<input type="hidden" value="" name="item_title[]">
<input type="hidden" value="sdsd" name="item_text[]">
</div>
Problem:
However, some of the blocks have more than one values for each field. For example, 'gallery' block, which has multiple image urls, image titles etc. I'm facing problem in finding a suitable way to put together the multiple values and submit.
Right now I'm adding them to a string with jQuery, separated with __. I can store the data and separate it, but the problem is that if I want to remove any image from it, it is very difficult because I have just added them in the string, so its hard to find it and remove it.
<div>
text item
<input type="hidden" value="gallery" name="item_name[]">
<input type="hidden" value="__http://img1.jpg__http://img2.jpg" name="img_path[]">
<input type="hidden" value="__img1__img2" name="img_title[]">
<input type="hidden" value="" name="img_desc[]"></input>
</div>
Question:
What would be the suitable way to send multiple values for the above block example, keeping in the mind that there will be multiple blocks having multiple input values?
Thanks.
Build a Javascript Array with all values.
Convert the array to JSON
Submit JSON as the value of the hidden field
On server side, use PHP json_decode function to convert JSON to PHP object or array

Best practice for handling multiple copies of the same input fields client side?

I have a set of input fields that are "stacked" on top of each other.
<!-- This controls which data set you're looking at -->
<select class="EditorInput" id="Selector" name="Selector">
<option value="0">Link a new vendor</option>
<option value="1">The ACME Company</option>
<option value="2">Widgets Unlimited</option>
</select>
<!-- These values change based on the selection above -->
<input type="text" name="Price" />
<input type="text" name="SKU" />
<input type="text" name="Field3" />
<input type="text" name="Field4" />
<input type="text" name="Field5" />
<input type="text" name="Field6" />
<input type="text" name="Field7" />
<input type="text" name="Field8" />
Only one set shows at a time, but all set's values are kept in browser until submit. When you make a selection in the drop down, all of the input fields in the group change to show the user the values relevant to the selection. For example, choosing "The ACME Company" in the select field would make The ACME Company's price show in the price field, The ACME Company's SKU show in the SKU field, etc.
All data and all changes are stored client side. When data is saved (via AJAX), all of the values for each set are saved to the server at the same time.
Since submission is via AJAX, all the values don't necessarily have to be stored in input elements.
I can think of two main ways to do this:
Method 1
A single set of input elements, with data stored in a javascript object. On change of the select, the correct data is read out of the javascript variable and inserted into the fields. Any changes the user made to the first set are saved into the variable first. Choosing to add a new set saves the current values to a variable, then clears the values in the form.
Method 2
Have one whole set of input fields per option. Hide the non-active input sets. Changing the select shows/hides the right set. Adding a new set copies one of the existing sets, inserts the new input elements into the dom and clears the values of those new input elements.
Method 3
Use HTML 5 data to store multiple values, like:
<input type="text" name="Field8" value="$7.95" data-value-vendor-1="$6.99" data-value-vendor-2="$2.65" data-value-vendor-3="$12.24"/>
Then use javascript to switch the values into and out of "storage".
Which option make more sense? Or is there a better way? Also, with Method 1, where would the values for each set be stored? On the Select Option?
I would use a JSON-based data store and recycle the inputs, then submit the JSON store instead of form data. There are plenty of libraries (you're already using jQuery) to help with this on both the client and server end of things.

Can I pass multiple checkbox values with one name?

I'm using Twitter's bootstrap and need to pass a delimited list of checkbox selections to my server for processing. The checkbox HTML looks like this:
<div class="controls">
<label class="checkbox"><input type="checkbox" name="my_match[]" value="190">TEST 190</label>
<label class="checkbox"><input type="checkbox" name="my_match[]" value="200">TEST 200</label>
<label class="checkbox"><input type="checkbox" name="my_match[]" value="210">TEST 210</label>
</div>
...
$.post("form.php", $("#form_id").serialize(), function(){
...
});
I'm passing the form values as a serialized string using jquery but the values are being sent like so:
my_match=190&my_match=200
Is it possible to send them in the following format?
my_match=190:200
I'm not sure if I need to change my HTML or this is something I need to handle with javascript. Any thoughts?
Something like this would do the trick:
<div class='controls'>
<label class="checkbox">
<input type="checkbox" name="my_match[]" value="190">TEST 190</label>
<label class="checkbox">
<input type="checkbox" name="my_match[]" value="200">TEST 200</label>
<label class="checkbox">
<input type="checkbox" name="my_match[]" value="210">TEST 210</label>
</div>
<form>
<input id='my_match' type='hidden' name='my_match[]' />
<button>Submit</button>
</form>
$('form').submit(function() {
var arr=[];
$('input:checked[name=my_match[]]').each(function(){
arr.push($(this).val());
});
$('#my_match').val(arr.join(':'));
alert($('#my_match').val());
// Prevent actual submit for demo purposes:
return false;
});
​
​
​
Try out the fiddle
Edit: This is basically exactly what Chase described in his answer.
I believe checkboxes with the same name return back with a comma separated list. What you could do is create a hidden field, append your checked checkbox values the way you want and then send the hidden field instead.
For anyone else who gets brought here by Google:
To the best of my knowledge, JavaScript is the only way to make them a string with separators because it gets complicated if you want a general solution which can deal with all possible desired separators and support the escaping the separator if it shows up in one of the value strings.
If at all possible, I strongly recommend just accepting the my_match=190&my_match=200 format and converting them on the server.
In PHP, that's automatic if you put the [] at the end of the name. In other languages, such as Python, there will usually be a special getter which returns a list rather than a single value. (For example, request.POST.getlist('my_match') in Django)
Relying on JavaScript makes your page more fragile since a flaky connection, a network hiccup, or a broken application-layer firewall could prevent the JavaScript from loading or delay it long enough for the user to try clicking Submit without it.
(And, if you disable the submit button until the JavaScript has loaded, you'll just annoy and/or frustrate your visitors and give them the impression that your site is shoddily built because everyone else does just fine without that restriction. Always keep in mind how your actions affect the first impression you make.)
...not to mention, depending on JavaScript when you don't strictly need to (eg. dropdown menus without a :hover fallback, forms that frivolously require JavaScript to submit, etc.) annoys people like me who use JavaScript whitelisting tools like NoScript to:
Make web advertising and "take a survey!" interstitials less annoying
Reduce the sluggishness of having tons of tabs and extensions open
Limit the chances that a 0-day exploit will succeed
If you absolutely must use JavaScript in a situation like this, be sure to use a <noscript> tag to warn people to reload with JavaScript enabled before they fill out the form.

Validation with specfic input types generated from an XML

I am in the midst of trying to come up with the best way for some validation within a generic MVC based XML which outputs the following.
<input name="xxxx" value="xxxx" ValidationType="Email" IsRequired="True" />
Basically if things contain certain elements, we validate it, if it's required than we do, if not, we don't etc etc. I tried some things but it seems the best way to do this would be a the JQuery "contains" method. I also know that that "ValidationType" is not really a valid attribute of input, but the XML outputs it this way. Any feedback would be appreciated. Thanks. I'm trying to do this as non complicated as possible :)
I would recommend using jquery validate plugin. You can validated elements with class-based attributes and add custom validation if need be. for example, should you need an input required. The output would look like this.
<input name="xxxx" value="xxxx" class="required" />
for email validation you can use
<input name="xxxx" value="xxxx" class="required email" />
Then execute the .valid() function to validated

Categories

Resources