JQuery replace elements within string - javascript

I have a string that contains HTML data, for example:
<div data-type="date" class="form-group">
<label class="control-label col-sm-5" for="dateInput">Date Input:</label>
<div class="col-sm-3">
<input type="text" name="dateInput[]" class="form-control date_picker" id="dateInput">
</div>
</div>
<div data-type="date" class="form-group">
<label class="control-label col-sm-5" for="dateInput">Date Input:</label>
<div class="col-sm-3">
<input type="text" name="dateInput[]" class="form-control date_picker" id="dateInput">
</div>
</div>
I asked this question before presuming I was working with the DOM. However, this is just a string. The first thing I do is to remove the data attribute from the string:
$("#content").find(".form-group").each(function() {
var html = $(this).attr('class', 'form-group')[0].outerHTML.replace(/ data-(.+)="(.+)"/g, "");
});
Next, you can see that both input elements have an id of dateInput. What I need to do now is to change this value so that it is unique, using something like an incrementing number. So, the first input should have dateInput1 and the second dateInput2.
How can I achieve this? If possible, it would also be good to change the for value in the label to match the id.
Thanks
Update
If I do:
$("#content").find(".form-group").each(function() {
var html = $(this).attr('class', 'form-group')[0].outerHTML.replace(/ data-(.+)="(.+)"/g, "");
$(this).find('input[type="text"]').attr('id', this.id+$(this).index()+1);
dataArray.push(html);
});
It does not seem to update. I have an example fiddle here https://jsfiddle.net/mLgrfzaL/4/

You can use jQuery for evaluating the string in order to navigate it as DOM tree:
var string = "<div><span>Hello</span></div>";
var $parsedDom = $(string);
$parsedDom.children(); // => <span>Hello</span>
In your case, it is not clear to me where you want to apply it.
Answering your other questions:
$("#content").find(".form-group").each(function(index) {
//$(this).attr('class', 'form-group') has no effect:
// you have already found the nodes with this class
// removing the "data-" (why?)
$(this).removeAttr("data-type");
//modifing the id
var $thisInput = $(this).find('input');
var oldId = $thisInput.attr('id');
$thisInput.attr('id', oldId + index);
});
Eventually you can loop on element attribute for removing every attribute starting with "data-".

You should cycle each input having id equal to dateInput, then append to its old value index + 1 (since it is zero-based).
$("input[id='dateInput']").each(function(index, value) {
var old_id = $(value).attr("id");
var new_id = old_id + (index + 1);
$(value).attr("id", new_id);
});

Use .index() to get a unique number in the each loop:
$("#content").find(".form-group").each(function() {
// other code
$(this).find('input[type="text"])
.attr('id', this.id+$(this).index()+1);
});

Related

Show/Hide Form elements based on json response

I make an api call and get a json Response that looks like this:
{"Field":"Amount","FieldName":"Amount","FieldType":"Numeric","MaximumLength":128,"MinimumLength":0,"Options":"Mandatory"}
The api call Returns between 5-10 of These objects.
In my html i have the fields inside a form, and they look as follow
<div class="form-group">
<label class="col-md-4 control-label" for="Amount">Amount</label>
<div class="col-md-4">
<input name="amount" class="form-control input-md" id="amount" type="text" placeholder="placeholder">
</div>
</div>
Now, depending on the json repsonse, i Need to show/hide different fields. Additionally, i Need to pass the min and max length, aswell as whether it's required or not ("Options":"Mandatory", in this example) Attributes to html, so the front end is already validate (obviously, further validation will be done server-side).
What's the best way to do this?
Edit:
I hide the Form Elements by using class="hidden". Also, every form element has a class that is identical to the id of the form element.
What i've tried so far is the following:
var ids = [];
for(var item in data) {
ids.push(data[item]['Field']);
$("." + ids[ids.length]).removeClass("hidden");
}
So in the above example, what i was hoping would happen in the first Iteration is that
$("." + ids[ids.length]).removeClass("hidden");
changes to
$(.Amount).removeClass("hidden");
and therefor show the form element.
Thanks
The problem is in this line
$("." + ids[ids.length]).removeClass("hidden");
When you push one element to ids array the length becomes 1 and your element is in 0th position but you are accessing element in first position.
To correct it change the line to
$("." + ids[ids.length - 1]).removeClass("hidden");
I ended up solving it like this:
var ids = [];
var minlength = [];
var maxlength = [];
var required = [];
for(var item in data) {
//push values into array
ids.push(data[item]['Field']);
maxlength.push(data[ids.length-1]['MaximumLength']);
minlength.push(data[ids.length-1]['MinimumLength']);
required.push(data[ids.length-1]['Options']);
//removes the class hidden and therefor shows the Element
$("." + ids[ids.length-1]).removeClass("hidden");
//adds the Attribute minlength to the html element
$("#" + ids[ids.length-1]).attr('minlength', minlength[minlength.length-1]);
//adds the Attribute maxlengthto the html element
$("#" + ids[ids.length-1]).attr('maxlength', maxlength[maxlength.length-1]);
//if the value in the Array is "Mandatory", adds the Attribute "required" to the html element
if (required[ids.length-1] == "Mandatory") {
$("#" + ids[ids.length-1]).attr('required', "required");
}

change label foreach element in html using javascript

I am using both html and velocity and came up with this code. The names and images are stored in an array and this is the code I used to display each of the contents of this array to the page.
#foreach($starter in $starter)
<div class="product">
<div class="color"><img src= "$starter.img" width="100" height="100"></div>
<span class="product-name">$starter.name</span>
<div class="compare-wrap">
<input type="checkbox" id="">
<label id="view">Compare</label>
</div>
</div>
#end
I wanted the label to change from "Compare" to "View Compare" while at the same time storing its id in the array upon checking their correspondng check box. I eventually came up with this code:
var checkedArray = [];
$(":checkbox").change(function(){
if((this).checked){
checkedArray.push(this.id);
document.getElementById('view').innerHTML = "<a href='/compare'>View Compare</a>";
}
else{
checkedArray.splice(checkedArray.indexOf(this.id), 1);
document.getElementById('view').innerHTML = 'Compare';
}
var str = checkedArray.join(', ');
alert(str);
});
but it seems it is only applicable to the first content of the array. Any idea how I can use a foreach code at this point?
document.getElementById() only supports one name at a time and only returns a single node not an array of nodes. You should use a class:
var views = document.getElementsByClassName('view');
var i = views.length;
while(i--) {
views[i].innerHTML = "Compare";
}
HTML
<label class="view">Compare</label>
Element ID must be unique.
Hope it helps.

Foundation checkboxes stop working with jQuery

If you go here http://passion4web.co.uk/DigiPics/upload and upload a photo, you'll see it brings up some checkbox options to brighten, distort. etc. I am using jquery to clone #photo-template so I can use it multiple times but the problem I am having is the checkboxes will not change when clicked.
This only seems to happen when I add foundation checkboxes to the page using javascript. Here is my method of adding them:
var $template = $("#photo-template");
var $addedPhotos = $("#added-photos");
$addedPhotos.html("");
if(response.length > 0)
{
for(var i in response)
{
var options = response[i];
var template = $template.clone();
template.find(".photo").attr("src", options['Photo URL']);
template.find(".brighten").prop("checked", options['Brighten']);
template.find(".sky").prop("checked", options['Sky']);
template.find(".grass").prop("checked", options['Grass']);
template.find(".distortion").prop("checked", options['Distortion']);
template.find(".description").val(options['Description']);
$addedPhotos.append(template.html());
}
}
You are not using the for attribute of label correctly. An excerpt of your HTML is:
<div class="switch round">
<input type="checkbox" class="sky" name="sky">
<label for="sky"></label>
</div>
The value of the for needs to match an id of a checkbox. It should be:
<div class="switch round">
<input type="checkbox" class="sky" name="sky" id="sky">
<label for="sky"></label>
</div>
Unfortunately since you are cloning it, you also need to make these id's unique. One possible solution:
template.find(".sky")
.prop("checked", options['Sky'])
.prop("id", "sky" + i)
.next() //get the label after it
.prop("for", "sky" + i);

Clone and change classname +1 and name of fields

I am trying to figure out how to clone this div so that the cloned version has product 2 as its class name as well as the input nams to have rate2 and notes2.
<div class="product1">
<input id="rate1" name="rate1" type="number">
<input name="notes" type="text">
<div>
Trying to append in here ****
<div class="sixteen columns" id="addproduct">
<label><i class="fa fa-plus-square"></i> Add another product</label>
</div>
=================================================================================
I have a rough idea of how to clone it but thats as far as my knowledge goes. I have looked at other posts and can't see an easy way of doing it.
JQuery-
$(document).ready(function(){
$("#addproduct").click(function(){
$(".product1").clone().appendTo("body");
});
});
Thanks for any help!
Why don't you try to keep a counter for sake of simplicity and increment it every time you add a new row (product). Something like this:
$(document).ready(function(){
// the counter:
var productID = 1;
// the click handler:
$("#addproduct").click(function() {
// clone last added product:
var nextProduct = $(".product" + productID).clone();
// add corresponding classes (remove old first):
nextProduct
.removeClass('product' + productID)
.addClass('product' + (++productID));
// update id and name to the first input:
nextProduct.find('input').eq(0).attr({
id: 'rate' + productID,
name: 'rate' + productID
});
// update name of the second input
nextProduct.find('input').eq(1).attr('name', 'notes' + productID);
// append to the body:
$('body').append(nextProduct);
});
});
This should do the job, although I'd recommend adding some identifiers to the two inputs (e.g. different class names, so you would avoid using the .eq() expression.
Live demo: http://jsbin.com/puluf/1/edit
Hope this helps!
Well I suggest you to use product-1 ,product-2 and so on as your ID and maybe product as your class name. By doing so, you can come up with something like this:
$("#addproduct").click(function(){
var temp = $(".product").last().prop('id').split("-");
$(".product").last().clone().appendTo("body");
var result = parseInt(temp[1]) + 1;
//assume this last product is the one that already added
$(".product").last().prop("id", "product-"+result);
});
Another way:
$("#addproduct").click(function(){
var temp = $(".product").last().prop('id').split("-");
var result = parseInt(temp[1]) + 1;
var html = $(".product:nth-child(1)").html();
$(".product").last().after('<div id="product-'+result+'" class="product">'+html+'</div>');
});
Edit, updated (v3)
Try
html (added 1 to end of attribute name , i.e., substitute notes1 for notes)
<input name="notes1" type="text" />
js (v3)
$(document).ready(function () {
$("#addproduct").on("click", function () {
var clone = $("[class^=product]:last")
.clone(false, false)[0].outerHTML.replace(/(\d)/g, function(a) {
return parseInt(a) + 1
});
$(clone).appendTo("body");
// console.log($(clone).attr("class"));
});
});
jsfiddle http://jsfiddle.net/guest271314/z2nxe84e/

How to get the value of textbox using id in javascript

I want to get the value of input boxes based on id and name.
Since my id is having comma its not accepting. When i remove comma and one of the id,it shows perfectly.
But, I will get the id as "Text,Demo_1" only. How can i get the value based on this id??
here is the code
HTML
<div id="Text,Demo_1" class="span12">
<label>Notes or Concerns</label>
<div class="control-group">
<input type="text" value="hi" name="view1" class="recommend">
<input type="text" value="hi2" name="view1" class="recommend">
<input type="text" value="hi3" name="view1" class="recommend">
</div>
</div>
Js part
$(function() {
var values = $('#Text,Demo_1 input[name="view1"]').map(function() {
return this.value;
}).get();
alert(values);
});
Get value by Name :
$("[name='view1']").val()
Get value by ID :
$("#[textbox_ID]").val()
Get all text values in array
var inputTypes = [];
$('.control-group input[name="view1"]').each(function(){
inputTypes.push($(this).val());
});
Use an array,
$(function () {
var values = [];
$('#TextDemo_1 input[name="view1"]').each(function () {
values.push($(this).val());
});
console.dir(values);
});
You should escape your comma with \\
var values = $('#Text\\,Demo_1 input[name="view1"]').map(function () {
return this.value;
}).get();
Demo: http://jsfiddle.net/M8Jmz/
But while it works you should consider changing an id to a proper identifier.
Use jQuery selectors to match the begining and end of the ID:
var values = $("div[id^='Text'][id$='Demo_1'] input[name='view1']").map(function() {
...
Edit: Explanation.
[id^='Text'] => Every element which id starts with "Text"
[id$='Demo_1'] => Every element which id ends with "Demo_1"
Putting them together will select every element that match both rules.
var values = $('input[name="view1"]').val();

Categories

Resources