Converting pairs of input elements into json - javascript

I have a simple ui which has a link that says "add item". When this is clicked, a pair of input boxes appears below it. If it is clicked again, yet another pair appears. I'm trying to think of the best way to generate these elements and turn it into some sort of json array of key value pairs (the first input element in each pair being the key and the second input element being the value).
Right now I just have a counter and I generate the ids using it, such as (in the click event of the "add item" link):
$('#features').append('<input id="feature-name-' + self.featureCount + '" type="text" name="asdf" /><a class="delete-feature" data-id="' + self.featureCount + '">Delete</a><input id="feature-description-' + self.featureCount + '" type="text" name="asdf" />');
I don't know what to use as the "name" attributes in order to make it easy to create a json array from them.

you can do something like this without using id attributes.
$('#features').append('<div><input type="text" />
<a class="delete-feature" data-id="' + self.featureCount + '">Delete</a><input type="text" /></div>');
And your javascript,
var yourArray=[];
$('#yourButton').click(function(){
$('#features div').each(function(){
var div=$(this);
var k=$('input:first',div).val();
var v=$('input:first',div).next().val();
yourArray.push({key:k, value: v});
});
});

It doesn't matter what you use for a name attribute, so long as there name and description names are different. Let's say that these elements are all appended to a form with the id myform. Give each pair its own wrapper object. Here, I've used a div, but a fieldset is equally appropriate.
$('#features').append(
'<div class="feature-div">
'<input id="feature-name-' + self.featureCount + '" type="text" name="asdf" />' +
'<a class="delete-feature" data-id="' + self.featureCount + '">Delete</a>' +
'<input id="featurena-description-' + self.featureCount + '" type="text" name="asdf" />' +
'</div>');
Now, it's possible to extract each pair sensibly:
var myarray = [];
$('#myform .feature-div').each(function(i, v) {
myarray.push([
$('input[name=name]', v).val(), $('input[name=description]', v).val()]);
});
Or however you want the data to be presented.

Related

Remove parameters before sending FORM POST

I have page with one form made in C# on the page there are several HTML elements. On button click I am using jQuery and add hidden fields than I submit form to external domain. Now the issue is, that it is sending all the parameters which I don't need. Is there any way that I can send only parameter that I need. I want to send parameter only in body.
Is there way to clear form parameter before adding parameter
jQuery Code
$("#aspnetForm").attr("action", "www.example.com");
$("#aspnetForm").attr("method", "post");
var params = a.split('?')[1].split('&'); /*custom string with key/value and sperated with & */
$.each(params, function (index) {
var paramsV = params[index].split('=');
$("#aspnetForm").append('<input type="hidden" name="' + paramsV[0] + '" value="' + paramsV[1] + '" /> ');
});
$("#aspnetForm").submit();
There more than 50 HTML element are added dynamically in my form and at each load it have different id. So I cannot disable those element in Jquery or javascript
I am using SharePoint 2013, it have its own master page where it add lot of elements which I don't have control, so I cannot individually disable them.
What I did is I created dynamically form add required parameter and then submit it.
Hope it can help somebody
$("#frm").remove(); /** remove extra frm before creating it **/
var frm = $('<form id="frm" action="' + _url + '" method="POST"></form>');
var params = a.split('?')[1].split('&'); /*custom string with key/value and sperated with & */
$.each(params, function (index) {
var paramsV = params[index].split('=');
frm.append('<input type="hidden" name="' + paramsV[0] + '" value="' + paramsV[1] + '" /> ');
});
frm.appendTo(document.body).submit();

Jquery/Dropzone.js Get the current index of an added image

I am building a custom Dropzone.js: http://www.dropzonejs.com/ layout. The upload is working well. I am wanting to save additional data in the form that the Dropzone is in for a specific post.
I need to index the array so that all the data is posted is relevant in the array.
The 'previewTemplate' allows for strings only - no function.
eg: lead_image[ INDEX HERE ][filename]
uploader.dropzone({
url: "/admin/upload",
acceptedFiles: 'image/*',
thumbnailWidth: 80,
thumbnailHeight: 80,
parallelUploads: 20,
autoProcessQueue: true, // Make sure the files aren't queued until manually added
clickable: ".fileinput-button", // Define the element that should be used as click trigger to select files.
previewsContainer: "#previews", // Define the container to display the previews
init: function() {
this.on("addedfile", function(file) {
var index = $('li.image').length;
});
},
previewTemplate: '<li class="image row dd-item">' +
'<div class="col-sm-1 dd-handle">' +
'<span class="preview">' +
'<img data-dz-thumbnail />' +
'</span>' +
'</div>' +
'<div class="col-sm-8">' +
'<p><span class="name" data-dz-name></span> | <span class="size" data-dz-size></span></p>' +
'<input type="hidden" class="form-control" name="lead_image[ INDEX HERE ][filename]" data-dz-name/>' +
'<input type="text" class="form-control" name="lead_image[ INDEX HERE ][title]" value="" placeholder="Title" />' +
'<input type="text" class="form-control" name="lead_image[ INDEX HERE ][alt]" value="" placeholder="Alt Tag" />' +
'<input type="text" class="form-control" name="lead_image[ INDEX HERE ][caption]" value="" placeholder="Caption" />' +
'<input type="text" class="form-control" name="lead_image[ INDEX HERE ][sort]" value="" placeholder="Sort Order" />' +
'<strong class="error text-danger" data-dz-errormessage></strong>' +
'</div>' +
'<div class="col-sm-2">' +
'<button data-dz-remove class="btn btn-danger delete"><i class="glyphicon glyphicon-trash"></i><span>Delete</span></button>' +
'</div>' +
'</li>',
});
I am having difficulty passing the template the index of the current item as these items are passed through later.
Has anyone dealt with this or can see a solution? I am currently trying to inject the file name as the index as a solution, but this isn't the best way to go in my mind.
Thanks in advance for taking the time to help.
bI sorted this in the end.
init: function() {
this.on("success", function(file, responseText) {
console.log(responseText);
// Create the hidden fields
// Created_at
file.createdat = Dropzone.createElement("<input type=\"hidden\" class=\"form-control input-sm\" name=\"" + this.options.inputName + "[" + responseText.id + "][created_at]\" value=\"" + responseText.created_at + "\" />");
file.previewElement.appendChild(file.createdat);
}
}
On the init function, you are basically waiting to hear back from Dropzone of the successful uploaded. So, depending on your server side implementation, you can pass back any data you want about the file. In my case, I stored it in the DB and returned the row's info.
From there, to save that information in in the current post, I just created some hidden fields to store the data and then repeated the above for each hidden field I wanted. You can of course add other non-hidden fields for things like alt tags, titles or anything you like.
The index I was after in the the responseText: this.options.inputName + "[" + responseText.id + "][created_at]
Hope it helps.
As a side note, you can also do the same thing when loading files that have been stored on the server that you want to retrieve for this specific post. Just Google mockfile and dropzone and you should find a million results helping you. Its the same principle.

How do I append html elements with varying id tags and text into my javascript?

My current page looks like this WITHOUT the input box. The problem I'm having is with the input. I'm going to have multiple controls with the same id name, and I want the value to be different for each row. What should I do to automate this? If I hardcoded it, I would still get the same ID tag on each loop iteration. My goal is to be able to add and delete entire target groups at the end
Target Name: text <--- what it looks like now
Command Line: [ input box ] <----- desired output
Build Env: [ input box ]
Rel Out: [ input box ]
Rel Log: [ input box ]
Dep: [ input box ]
my JS looks like:
for (var i = 0; i < records.length; i++) {
var row = $('<tr></tr>');
row.append($('<tr></tr>').text("Target Name: " + records[i].TargetName));
row.append($('<tr></tr>').text("Command Line: " + records[i].CommandLine));
row.append($('<tr></tr>').text("Build Environment: " + records[i].BuildEnvTypeName));
row.append($('<tr></tr>').text("Relative Output Path: " + records[i].RelativeOutputPath));
row.append($('<tr></tr>').text("Relative Log Path: " + records[i].RelativeLogPath));
row.append($('<tr></tr>').text("Dependencies: " + records[i].Dependencies));
$('#AddTargetTable').append(row);
}
the input box part I want to append for each part (this is specific for the target name one):
<div class="control-group">
<div class="controls">
<input type="text" id="target-name" value="<% =TargetName %>" />
</div>
</div>
if you pass a unique identifier along with your record data you can add that identifier to each row. You don't need element ID's for tasks like this.
/* add identifier to start of row */
var row = $('<tr data-id="'+records[i].id +'"></tr>');
Then when you interact with a row you can pull the data-id using jQuery.data() method.
As for the input's you need to use html() instead of text() for cell data.
A simple template function will help keep the clutter down
function inputTemplate( value, type){
return ' <div class="control-group">'+
'<div class="controls">'+
'<input type="text" value="'+value+'" data-type="'+type+'" />'+
'</div>'+
'</div>';
}
Adding cells:
row.append($('<td>').html("Command Line: " + inputTemplate( records[i].CommandLine, 'Command')));
Now add a change handler for the input's. Will use similar row traversal approach for delete row.
$('.controls input').change(function(){
var rowId = $(this).closest('tr').data('id');
var newValue=$(this).val();
var fieldType= $(this).data('type')
alert('new value for '+ fieldType +' in row ' + rowId +' is ' + newValue );
updateServer( rowId, fieldType, newValue);
})

JSF param POST parameter not retrieving

I've been looking an answer, but I don't find anything.
I got a JSF page with a button. This button call a JavaScript function :
function postAdd(id) {
var quant = document.getElementById("hell:quantite");
$('<form action="addto.xhtml" method="POST">' +
'<input type="hidden" name="productkey" value="' + id + '">' +
'<input type="hidden" name="howmany" value="' + quant.value + '">' +
'</form>').submit();
}
This works fine, I've tested it.
But in my addto.xhtml page, when I call param.productkey and param.howmany, I got nothing.
I used this method on other page and works fine but here, it doesn't work...
Any idea ?
Thanks.
The answer was to add to form inside the JSF page directly and get all parameters with #{function(param[form:idOfInput]}

how to delete a value between <input> tags?

I'm creating checkboxes using JQuery as following:
$('<input type="checkbox" ' + 'id=' + (i+1) + '>' + (i+1) + '</input><br/>')
Then later it is removed whenever the user checks the box in:
if (this.checked) {
$(this).remove();
}
However, The input box is deleted, but the number (id) stays on the page, along the <br/> Tag, so I can see the #i there on the HTML Page.
I would like to remove them as well.
So, to in order to make my question as complete as possible, here is how the HTML is laid:
<input id="1" type="checkbox">
1
<br>
Could someone please give me a clue how to remove #i and <br/> from the page?
Thanks
as stated by other answers - input don't have closing tags
You will still need to remove all id and <br />. You can find those with .next() function in jquery. You should put your id in <label> or <span>.
Then. for example:
$(this).next('label').remove();
$(this).next('br').remove();
$(this).remove();
Code can be written shorter but it's for you to see how it works.
The text in <input> text boxes is not set with a textnode (like for textareas), but with the value attribute. (Sorry for the confusion)
Yet, you want to have a checkbox. Best, create a <label> for it, instead of a text node plus a <br /> (which is not handleable with jQuery):
<div class="inputcell">
<input type="checkbox" id="check5">
<label for="check5">5</label>
</div>
With this DOM, you can easily remove the whole box by $("#check5").parent().remove(). Note that single numbers are no valid element ids.
that's because input tags don't have closing tags and remove ignores everything after the >, change this:
$('<input type="checkbox" ' + 'id=' + (i+1) + '>' + (i+1) + '</input><br/>')
to:
$('<input type="checkbox" ' + 'id=' + (i+1) + 'value="' + (i+1) +'"><label>'+ (i+1) +'</label>')
$(this).next('label').andSelf().remove();
input tags don't have closing tag, to create a checkbox you just need the following:
$('<input type="checkbox" ' + 'id=' + (i+1) + '>');
and if you want also to use a label for that checkbox, create appropriate label or any other element, because you can't put closign tag for input and a text between them

Categories