Create JSON from dynamic form generation - javascript

I'm creating a dynamic form. Which has drag and drop feature. When Admin has completed the form creation,I have to save form details in Db.
Fiddle link for Form Generation
I don't know from where to start or how to traverse the form to save in json format.
I was to save Json format like this
var formDetails = [
{
"type":"textbox",
"label":"Please enter your name",
"id":"txt-1465133974748"
},
{
"type":"select",
"label":"Please Select Option",
"id":"select-1865133974748",
"fieldOptionDetails":[
{
"fieldLabel":"Option 1",
"fieldValue":"1"
},
{
"fieldLabel":"Option 2",
"fieldValue":"2"
}]
}];

$('#btnSaveForm').on('click',function(){
var formdetail = [];
$("ul#form-Container li").each(function(){
var input = {};// crate an object
// access each form li elements and add the attributes to input object
input.type = "textbox / select"; // depending on your form field type
input.label = "form field label"; // similarly add other fields also
formdetail.push(input) ; // add object to formdetail array
});
JSON.stringify(formdetail); // use josn.stringify(array)
});

Related

Value Given when tick box is checked :Undefined Array Key

When check box is selected, it copies value from customer to invoice party. So I am assuming that when check box selected. value is automatic. but it is saying undefined array key.
function EnableDisableTextBox(tickSame) {
var shipper = document.getElementById("iP");
var customer = document.getElementById("consignee").value;
document.getElementById("iP").value=customer;
shipper.disabled = tickSame.checked ? true : false;
if (shipper.enabled) {
shipper.blur();
}
}
I hope you are submitting the form to the server side. Disabled inputs will not submit data when submitting the form. Instead you can use readonly attribute to make to non editable (Even you can make it look like disabled with css)
function EnableDisableTextBox(tickSame) {
var shipper = document.getElementById("iP");
var customer = document.getElementById("consignee").value;
document.getElementById("iP").value=customer;
shipper.readonly= tickSame.checked ? true : false;
if (shipper.readonly) {
shipper.blur();
}
}

How to add multiple input field inside a div dynamically using JavaScript/jQuery?

I need to create some multiple input field dynamically on onkeypress event using JavaScript/jQuery.
I have one text-box,when user is entering any key on that text area two input field and second text-box is opening. When user will enter any key on second text box again another two input field and third text-box will open and so on. There is also a cross button is creating to close each individual set of text-box. In my current code I doing this putting all field static as user may create many numbers of input field so that I want to create those in dynamically with different name and id.
My code is in this Plunkr.
EDIT: Misunderstood question, answer below
This can easily be done if you have a specific field in which to create the input fields. For example, I will load input fields into document.body
Everytime you call newinput() an input field is created in parent who's id starts at input0 and increments each time
var id = 0;
var newinput = function() {
var parent = document.body
var field = document.createElement("input")
field.className = "myclassname"
field.style = "display:block;"
field.id = "input" + id;
parent.appendChild(field);
id += 1;
}
<body>
<div>Click plus to add input</div>
<button type="button" name="button" onclick="newinput()">+</button>
</body>
In your case, it looks like you want to add a group, you can do this:
var fieldgroup = document.querySelector(".questionshowp .form-group").cloneNode(true); // (1)
var addinput = function(){
var parent = this.parentNode.parentNode.parentNode; // (2)
var n = parent.querySelectorAll(".form-control").length
var f = fieldgroup.cloneNode(true);
f.children[0].id = "question"+n // (3)
f.querySelector(".secondsec").querySelector("button.btn-success").onclick = addinput // (4)
parent.insertBefore(f,parent.querySelector(".clear")); // (5)
}
Create a copy of a field-group to be used as a template
Get the container of input fields
Set the input field id with regard to total number of form-groups in parent
Make sure template applies addinput() to button
Insert input form before end of parent form
The easiest way apply this function to all + buttons is with JQuery
$("button.btn-sm.btn-success").on("click", addinput)
This would need to be located at the bottom of your html file, and below addinput() definition
EDIT: Real Answer
Turns out I wrote all that and just realized I misunderstood your question.
Still we can use the same principle to do what I believe you are asking
master = document.querySelector(".aquestionpart"); // (1)
form = document.querySelector(".questionparts"); // (2)
function show(){
var f = form.cloneNode(true);
var n = master.querySelectorAll(".questionparts").length;
f.id = "questionparts"+(n+1); // (3)
f.querySelector("#questions").onkeypress = show; // (4)
this.parentElement.parentElement.querySelector("#questionparts"+ n + " > .questionshowp").style ="display:block;"; // (5)
this.onkeypress = undefined; // (6)
master.insertBefore(f,master.children[master.children.length-1]) // (7)
}
form.querySelector("#questions").onkeypress = show; // (8)
form = form.cloneNode(true); // (9)
Get poll container
Get poll question form to use as template
Set new poll question form id with respect to number of others
Set show function to new poll question
Show multiple choice
Make sure subsequent keypresses dont create more questions
Insert question before .clear
sets up first question to show
creates copy of fresh question to use as template
With this your current scripts.js is unnecessary, and .aquestionpart must look like this for proper formatting
<div class="aquestionpart">
<div class="questionparts" id="questionparts1">...</div>
<div class="clear"></div>
</div>
From within .questionparts be sure to remove onkeypress="show();" from input. It should look like this.
<input name="questions" id="questions" class="form-control" placeholder="Questions" value="" type="text">
And finally an interesting note is that both of the scripts I've provided can be used together! (With some slight modifications)
//Author: Shane Mendez
var fieldgroup = document.querySelector(".questionshowp .form-group").cloneNode(true);
var addinput = function(){
var parent = this.parentNode.parentNode.parentNode;
var n = parent.querySelectorAll(".form-control").length
var f = fieldgroup.cloneNode(true);
f.children[0].id = "question"+n
f.querySelector(".secondsec").querySelector("button.btn-success").onclick = addinput
console.log(parent)
parent.insertBefore(f,parent.children[parent.children.length-1]);
}
master = document.querySelector(".aquestionpart");
form = document.querySelector(".questionparts");
function show(){
var f = form.cloneNode(true);
var n = master.querySelectorAll(".questionparts").length;
f.id = "questionparts"+(n+1);
f.querySelector("#questions").onkeypress = show;
console.log(this)
this.parentElement.parentElement.querySelector("#questionparts"+ n + " > .questionshowp").style ="display:block;";
this.onkeypress = undefined;
master.insertBefore(f,master.children[master.children.length-1])
$(f.querySelectorAll("button.btn-sm.btn-success")).on("click", addinput)
}
form.querySelector("#questions").onkeypress = show;
form = form.cloneNode(true);
$("button.btn-sm.btn-success").on("click", addinput)
If you put this in your scripts.js file and put that at the bottom of your body tag, then the only thing left is the - buttons.
You can use this Press to add multiple input field inside a div dynamically using jQuery. Here you only need to call the function that takes two parameter HTMLElement and config like:
$(".addInput").click(function() {
build_inputs($(this), config);
});
In the config you can add numbers of inputs form config like:
let config = {
title: "Slides",
forms: [
{
type: "text",
name: "name",
class: "form-control mb-2",
placeholder: "Enter Data..."
},
{
type: "file",
name: "image",
class: "btn btn-light btn-sm mb-2 btn-block"
},
{
type: "number",
name: "mobile",
class: "form-control mb-2",
placeholder: "Enter Data..."
}
],
exportTo:$('#getData')
};

Fill a field with a dynamic name in CasperJS

I can succesfully logged in a website and then fill a form and get the results.
Now im trying to do this for anyone who uses my app. The problem is that the form I have to fill has a field name that changes to the number of user.
like this:
casper.thenOpen('http://www.foo.com/index.html', function() {
this.fill('form[action="/cgi-bin/login.cgi"]', { login: user,password:pass }, true);
this.click('input[type="submit"][name="enter"]');
this.wait(5000,function(){
this.capture('eff_ss2.png');
});
});
Everything is fine untill here (I read the login and pass with casper.cli.raw.get();
and then I do this:
this.fill('form[action="../foo.cgi"]', {
'from_city': ori,
'to_city': dest,
'plan_03231': 'whatev',
'aspp_03231': 'whatev'
}, true);
The 03231 will change according to the user who logged in. How can I do this dynamically? I already tried to make:
var plan = 'plan_0'+user;
var obj{}
obj[plan] = 'whatev'
this.fill('form[action="../foo.cgi"]', {
'from_city': ori,
'to_city': dest,
obj,
'aspp_03231': 'whatev'
}, true);
but is not working. Can somebody help me?
In your last snippet you have the id of the user in the user variable, but put an object into an object item place. This is not valid JavaScript. Since the object key is a composite, you need to set it using obj[''+id] = ''; syntax:
var obj = {
'from_city': ori,
'to_city': dest
};
obj['plan_0'+user] = 'whatev';
obj['aspp_0'+user] = 'whatev';
this.fill('form[action="../foo.cgi"]', obj, true);
An easier method where you don't need the explicit user id is simply selecting the form fields based on the beginning of the name attribute using the ^= attribute matcher and casper.fillSelectors:
this.fillSelectors('form[action="../foo.cgi"]', {
'*[name="from_city"]': ori,
'*[name="to_city"]': dest,
'*[name^="plan_0"]': 'whatev'
'*[name^="aspp_0"]': 'whatev'
}, true);

LocalStorage retrieving from arrays, confusion

Getting confused, creating a web app where people post notes, I have a field for subject and one for the actual note, when posted these should be saved into two arrays, when posted these should appear almost like a comment, with what you just entered in two fields, which did work but I want people to be able to save their notes, close the browser and return, below is the code that is not working, basically the user should be able to
Allow user to enter in values.
If local storage is available, Take values saved from arrays (which I tried converting to a string then convert back to a array using JSON, which is confusing) and fill the page
$("document").ready( function (){
//Each subjectField.value goes into array
var subjectInputArray = [];
//Each noteField.value goes into array
var noteInputArray = [];
//Color array holds color hex codes as values
var noteColourArray = [];
noteColourArray[0] = "#03CEC2";
noteColourArray[1] = "#ADC607";
noteColourArray[2] = "#ffdd00";
noteColourArray[3] = "#f7941f";
//Variable holds properties for note creation
var noteCreate =
{
noteCreateContainer : $("<article>", { id: "noteCreateContainer" }),
noteForm : $("<form>", { id: "noteFormContainer" }),
subjectField : $("<input>", { type: "text", placeholder: "Title", id: "subject"}),
noteField : $("<input>", { type: "text", placeholder: "Write a Note", id: "noteContent" }),
submitNote : $("<button>", { type: "submit", id: "post", text: "post"}).on( "click", (postNote))
}
//Variable holds properties for a note content (NOT SUBJECT);
var notePost = {}
//--------------------------------------------------------------------------------
//Test if local storage is supported
if( Modernizr.localstorage ) {
//Get current array/list
localStorage.getItem("subjectInputArray")
//Convert string back to array
var savedNoteSubjects = JSON.parse(localStorage["subjectInputArray"]);
//For each item in subject localStorage array, loop through an fill page with fields containing values
for(var i = 0; i < savedNoteSubjects.length; i++)
{
//Create container for post
//Apply noteCreateContainer's selected background color to the posted note
$("<article>").appendTo("body").addClass("notePostContainer").css("background-color", ($("#noteCreateContainer").css("background-color")));
console.log("local storage: " + [savedNoteSubjects]);
//Select last div of class notePostContainer to add input field, instead of adding 1+ input fields on each click to all classes using the same class name
$("<input>", {class: "subjectFieldPost", type: "text", value: savedNoteSubjects[savedNoteSubjects.length-1] }).appendTo(".notePostContainer:last-child").prop("disabled", true);
}
} else {
alert("Your browser does not support localStorage, consider upgrading your internet browser");
}
//--------------------------------------------------------------------------------
//Create/Set up fields required for user to input data
noteCreate.noteCreateContainer.prependTo("body");
noteCreate.noteForm.appendTo(noteCreateContainer);
//Loop through noteColourArray and append new button for each item
for (var i = 0, len = noteColourArray.length; i < len; i++) {
noteCreate.noteForm.append($("<button>", {class: "colourSelect", value: noteColourArray[i] }).css("background-color", noteColourArray[i]).click(setBackgroundColour))
}
//Change background colour on click
function setBackgroundColour()
{
$("#noteCreateContainer").css("background-color", noteColourArray[$(this).index()] )
return false;
}
noteCreate.subjectField.appendTo(noteFormContainer);
noteCreate.noteField.appendTo(noteFormContainer);
noteCreate.submitNote.appendTo(noteFormContainer);
//--------------------------------------------------------------------------------BELOW NOTE POST/OUTPUT FROM CREATING NOTE
//FUNCTION - CREATE NEW POST UPON CLICKING POST
function postNote()
{
//Add submitted value of subject field to array
subjectInputArray.push( $("#subject").val() );
//Convert array into string
localStorage["subjectInputArray"] = JSON.stringify(subjectInputArray);
//Add value of note field to array
noteInputArray.push( $("#noteContent").val() );
//Create container for post
$("<article>").appendTo("body").addClass("notePostContainer").css("background-color", ($(noteCreateContainer).css("background-color")) ) //Apply noteCreateContainer's selected background color to the posted note
//Select last div of class notePostContainer to add input field, instead of adding 1+ input fields on each click to all classes using the same class name
//Pull value from local storage subject array
$("<input>", {class: "subjectFieldPost", type: "text", value: subjectInputArray[subjectInputArray.length-1] }).appendTo(".notePostContainer:last-child").prop("disabled", true)
//Select last div of class notePostContainer to add input field, instead of adding 1+ input fields on each click to all classes using the same class name
$("<input>", {class: "noteFieldPost", type: "text", value: noteInputArray[noteInputArray.length-1] }).appendTo(".notePostContainer:last-child").prop("disabled", true)
return false;
} //End function
});
An earlier post I made in relation to my idea
button click temporarily changes div background color, not permanently as intended
var subjectInputArray = [];
...
localStorage["subjectInputArray"] = JSON.stringify(subjectInputArray);
You are setting your localStorage["subjectInputArray"] to an empty array every time your page loads.
How could you expect load anything useful from it?
Instead, try put localStorage["subjectInputArray"] = JSON.stringify(subjectInputArray); in postNote(), so every time user input something, you update the localStorage record.
Additionally,
var savedNoteSubjects = JSON.parse(localStorage["subjectInputArray"]);
this line should be inside the test local storage if block. Don't use it until it's confirmed to be available

How to get the #htmlDropDownList selected value?

I have a #htmlDropDownList as
#Html.DropDownList("MyList", new SelectList(Model.List, "Id", "Movie"))
in a mvc3 view.
How can I capture the selected value of this drop down list using javascript and use it to change the contents of the view according to the selected item?
To get the value is simple:
$('#MyList').val()
For the second part of the question I need more info.
UPDATE
How would we use the value?
//get the url for the movie description , define id as 0, so it is easier to replace lateron.
var moviedescriptionUrl = '#Url.Action("details", "movies", new { id = 0})';
//get the movieid
var movieID = $('#MyList').val();
//update a div
$('#movie-description').load(moviedescriptionUrl.replace('0', movieID));
Assuming I have an "details" action that return a partial view.

Categories

Resources