I've following problem: I use a clone script to clone input fields which are used for cms options. Depending on the field name the option arrays are created in the db.
I have following field at the moment:
options[categories][1][3]
and want to increase the first number by using a counter variable like:
options[categories][2][3]
options[categories][3][3]
...
However I'm not familiar with regular expressions so I hoped someone could provide a str.replace code which helps me to replace the first number with my counter variable.
Thanks in advance!
.......
Code:
.......
At the moment it looks like:
if ( $(clone).attr('name') ){
newid = $(clone).attr('name');
var position = newid.lastIndexOf("[");
newid = newid.substring(0, position)+ '[' + (counter +1) + ']';
$(clone).attr('name', newid);
};
Html field:
<input type="checkbox" value="1" name="options[categories][1][3]">
3 is the category id, 1 is the option I need the category for. The clone script would produce:
<input type="checkbox" value="1" name="options[categories][1][4]">
at the moment - but I need:
<input type="checkbox" value="1" name="options[categories][2][3]">
I think it's a regex problem because the easiest solution would be to search for [categories][anyvalue] and replace it with [categories][counter]
You could use a regular expression to replace the first number in brackets. Like this:
if ( $(clone).attr('name') ) {
var newid = $(clone).attr('name');
newid = newid.replace(/\[[0-9]*\]/, '[' + (counter + 1) + ']');
$(clone).attr('name', newid);
};
Related
Im passing a list objects to the view using Spring model attribute. And in the view im trying to populate set of inputs dynamically using jquery as below :
passing the list from the controller :
List<String> supplierNames = Arrays.asList("address1", "address2", "address3");
model.addAttribute("consumerAddresses", supplierNames);
view (jsp):
<div class="input_fields_wrap">
<div><input type="text" id='label1'><input type="text" id='address1'></div>
</div>
<script>
$(document).ready(function() {
var consumerAddresses = "${consumerAddresses}";
var max_fields = 10;
var wrapper = $(".input_fields_wrap");
for (i = 0; i < consumerAddresses.length; i++) {
$(wrapper).append('<div><input type="text" id="label' + i + '" value=' + consumerAddresses[i] + '/><input type="text"
id="address' + i + '" value=' + consumerAddresses[i] + '/></div>');
}
});
</script>
Now the issue is consumerAddresses are passed as array [address1, address2, address3] but in input fields its populated as [/ a/ d/ likewise. what has gone wrong here?
Inside consumerAddresses you have not an array, it's a string.
And then when you're trying to iterate over it you just take some chars from it.
You need to convert string to an array before iterating through it.
In this case you can use split method.
var consumerAddressesArray = consumerAddresses.replace(/[[\]']+/g,'').split(", ");
After this operations you will have
[
"address1",
"address2",
"address3"
]
inside your consumerAddressesArray variable.
And make sure that you have trimmed all rudimentary chars. I mean [, (space), ]. In my example I've used regex for that (.replace(/[[\]']+/g,'')). It will replace square brackets with empty string.
You can get value which is return by spring mvc in some jsp variable then use for-loop in jsp to iterate through that list i.e :
<%
//get value in jsp variable
//i.e :request.getAttribute("consumerAddresses");
//here i assumme consumerAddresses is variable in jsp which has that arry value
for(int x=0;x<consumerAddresses.length;x++) {%>
$(wrapper).append('<div><input type="text" id="label<%=x%>" value='<%=consumerAddresses[x]%>'/>
<input type="text" id="address<%=x%>" value='<%=consumerAddresses[x]%>'/></div>');
<%}%>
Note : Above code is not tested it might be having some syntax error .Also, you can do same using jstl .
I need something like an associative array that contains pairings of variable name / element ID.
Looping through this array/object, assign the element ID to the variable name that is its counterpart. Something like this:
jsFiddle
HTML:
<input id="fld_1" class="input" type="text" value="bob" /><br>
<input id="fld_2" class="input" type="text" value="fred" /><br>
<input id="fld_3" class="input" type="text" value="pat" /><br>
<input id="mybutt" class="btn" type="button" value="Test" />
JS:
objFields = {'f1':'fld_1', 'f2':'fld_2', 'f3':'fld_3'};
arrErrors = [];
$('#mybutt').click(function(){
alert('iii');
for (var key in objFields){
// eval(key = objFields[key]);
eval(key) = objFields[key];
alert('f1: ' +f1);
}
});
There is no requirement to using eval, I just need to turn the key into the variable name.
Where have I gone wrong?
Solution
JCOC611 got it right, but I wasn't clear in how I asked the question. As demo'd in this revised fiddle which implements JCOC611's solution, the variable/field names had to be used to get the value of the field contents, like this:
$('#mybutt').click(function(){
for (var key in objFields){
var tmp = objFields[key];
eval('var ' + key+ ' = $("#' +tmp+ '").val()');
}
});
If you know what you are doing and are absolutely sure about it, then use this:
eval(key + " = " + JSON.stringify(objFields[key]));
Or, if you want local variables:
eval("var " + key + " = " + JSON.stringify(objFields[key]));
Otherwise, I advice you implement one of the other answers.
You don't need that eval() at all, and you want to avoid it. All you really need to do is:
for (var key in objFields){
alert(key+': '+objFields[key]);
window[key] = objFields[key];
}
Will give you:
'f1':'fld_1'
'f2':'fld_2'
'f3':'fld_3'
Where:
f1 = 'fld_1';
f2 = 'fld_2';
f3 = 'fld_3';
If it is a global variable, it is as simple as:
window[key] = objFields[key];
or
window.key = objFields[key];
The second one is a bit less weird name immune.
The eval function runs a string add code and returns the result.
What your code did was evaluate the vague of key which is undefined and then tried to set it to a new value.
Is like writing 5=4;
Correct syntax:
eval('var ' + key + ' = ' + objFields[key]);
I have an input field which looks something like this...
<input type='hidden' name='myInput[1][sausages][0][]' value='123' />
I need to change the value in the third set of square brackets when a user clicks on a button...
so something like
$("a.mylink").click( function() {
$(this).siblings('input[name*=myInput]')..... CHANGE THE 0 to 1 in the third set of square brackets...
});
Any ideas how I can do this?
Try This:
$('input').attr('name',$('input').attr('name').replace(/\[\d+](?!.*\[\d)/, '[1]'))
Working Demo
You can use regex to replace the value like so:
var name = $('input [name*=myInput]').attr('name');
name.replace(/]$/, 'new value]');
$('input [name*=myInput]').attr('name', name);
The new value can be any number
This regex replaces the last bracket with a new value: newvalue ]
Or if you want to change the 2nd to last bracket you can use this regex:
name.replace(/]\[\]$/, 'new value][]');
Try this
var name = $('input[name*=myInput]').attr('name');
var indexOfThirdBracket = name.indexOf('[', name.indexOf('sausages')) + 1;
name = name.substring(0, indexOfThirdBracket) + '1' + name.substring(indexOfThirdBracket + 1);
$('input[name*=myInput]').attr('name', name);
http://jsfiddle.net/3A592/
UPDATE
Solution without hard code value 'sausages'
var name = $('input[name*=myInput]').attr('name');
var parts = name.split('[');
parts[3] = parts[3].replace('0', '1');
name = parts.join('[');
$('input[name*=myInput]').attr('name', name);
http://jsfiddle.net/56rtG/
use this code:
var counter = 1;
$('a.mylink').click(function(){
$(':text').attr('value', 'myInput[1][sausages][' + counter++ + '][]');
});
thanks for looking.
im still learning the more complex javascript and jquery coding so could do with some help as i have no idea about the following or even if its possible!
i need a better/simpler/shorter way of doing the following (please note i have removed the irrelevant validation etc coding):
'
function Findbox5( myform, box1, box2, box3, box4, box5, Storeall, s1, s2, s3, s4, s5)
{
//store values
Myform = document.forms.myform;
box1 = Myform.box1.value;
box2 = Myform.box2.value;
box3 = Myform.box3.value;
box4 = Myform.box4.value;
box5 = Myform.box5.value;
s1 = Myform.s1.value;
s2 = Myform.s2.value;
s3 = Myform.s3.value;
s4 = Myform.s4.value;
s5 = Myform.s5.value;
//set as one string
Storeall = s1 + ":" + box1 + ";" + s2 + ":" + box2 + ";" + s3 + ":" + box3 + ";" + s4 + ":" + box4 + ";" + s4 + ":" + box5 + ";" ;
// next function...
} '
as you can see i have 5 input boxes and relevant selects for each box(each select has 4 options:1,2,3,4.). when a user enters data into a box they choose a relevant option. all boxes and options must be entered then they submit the form.
this data will be emailed to me as the variable stored under storeall. which would be something like 1:1234;2:1324;1:3232;4:5434;2:3211;
so what i hope to do is simplify this data into the following with either a seperate function or the same one: 1:1234-3232;2:1324-3211;4:5434;
is this possible? or have i done it the easiest way?
any comments or help welcomed, thanks again
First, you'll want to group these things into a single element that can be iterated against. So if your HTML looks like:
<form>
<input name="s1" />
<input name="box1" />
<input name="s2" />
<input name="box2" />
...
</form>
Then it's probably better to do something like:
<form>
<div class="set">
<input class="s" name="s1" />
<input class="box" name="box1" />
</div>
<div class="set">
<input class="s" name="s2" />
<input class="box" name="box2" />
</div>
...
</form>
Now you've established some commonality among these elements, instead of just different names/IDs. Each set of inputs is grouped by the .set class, and within each set, you know there's going to be two inputs: one with the .s class, and one with the .box class. Now iterating against them with JQuery is easy:
var str = "";
$("form div.set").each(
function(index, element)
{
currentValueS = $(element).find("input.s").val();
currentValueBox = $(element).find("input.box").val();
str += currentValueS + ":" + currentValueBox + ";";
}
);
This uses JQuery's .each() function. .each() allows you to provide a function to perform on each of the elements that JQuery finds from the indicated selector. Here, your selector is form div.set, which means "all div elements that have the class of .set, and are found anywhere under any form element". For each of these elements, you'll need to find the value of the <input> element with the .s class, and also the value of the <input> element with the .box class. Then you just add those to your growing str variable.
If you want everything in the form, you should use serializeArray :
$('#my_form').submit(function() {
var str = '';
$.each($(this).serializeArray(), function () {
str += this.name + ":" + this.value + ";";
});
sendByMail(str);
return false;
});
I am using ASP.Net MVC along with Jquery to create a page which contains a contact details section which will allow the user to enter different contact details:
<div id='ContactDetails'>
<div class='ContactDetailsEntry'>
<select id="venue_ContactLink_ContactDatas[0]_Type" name="venue.ContactLink.ContactDatas[0].Type">
<option>Email</option>
<option>Phone</option>
<option>Fax</option>
</select>
<input id="venue_ContactLink_ContactDatas[0]_Data" name="venue.ContactLink.ContactDatas[0].Data" type="text" value="" />
</div>
</div>
<p>
<input type="submit" name="SubmitButton" value="AddContact" id='addContact' />
</p>
Pressing the button is supposed to add a templated version of the ContactDetailsEntry classed div to the page. However I also need to ensure that the index of each id is incremented.
I have managed to do this with the following function which is triggered on the click of the button:
function addContactDetails() {
var len = $('#ContactDetails').length;
var content = "<div class='ContactDetailsEntry'>";
content += "<select id='venue_ContactLink_ContactDatas[" + len + "]_Type' name='venue.ContactLink.ContactDatas[" + len + "].Type'><option>Email</option>";
content += "<option>Phone</option>";
content += "<option>Fax</option>";
content += "</select>";
content += "<input id='venue_ContactLink_ContactDatas[" + len + "]_Data' name='venue.ContactLink.ContactDatas[" + len + "].Data' type='text' value='' />";
content += "</div>";
$('#ContactDetails').append(content);
}
This works fine, however if I change the html, I need to change it in two places.
I have considered using clone() to do this but have three problems:
EDIT: I have found answers to questions as shown below:
(is a general problem which I cannot find an answer to) how do I create a selector for the ids which include angled brackets, since jquery uses these for a attribute selector.
EDIT: Answer use \ to escape the brackets i.e. $('#id\\[0\\]')
how do I change the ids within the tree.
EDIT: I have created a function as follows:
function updateAttributes(clone, count) {
var f = clone.find('*').andSelf();
f.each(function (i) {
var s = $(this).attr("id");
if (s != null && s != "") {
s = s.replace(/([^\[]+)\[0\]/, "$1[" + count + "]");
$(this).attr("id", s);
}
});
This appears to work when called with the cloned set and the count of existing versions of that set. It is not ideal as I need to perform the same for name and for attributes. I shall continue to work on this and add an answer when I have one. I'd appreciate any further comments on how I might improve this to be generic for all tags and attributes which asp.net MVC might create.
how do I clone from a template i.e. not from an active fieldset which has data already entered, or return fields to their default values on the cloned set.
You could just name the input field the same for all entries, make the select an input combo and give that a consistent name, so revising your code:
<div id='ContactDetails'>
<div class='ContactDetailsEntry'>
<select id="venue_ContactLink_ContactDatas_Type" name="venue_ContactLink_ContactDatas_Type"><option>Email</option>
<option>Phone</option>
<option>Fax</option>
</select>
<input id="venue_ContactLink_ContactDatas_Data" name="venue_ContactLink_ContactDatas_Data" type="text" value="" />
</div>
</div>
<p>
<input type="submit" name="SubmitButton" value="AddContact" id='addContact'/>
</p>
I'd probably use the Javascript to create the first entry on page ready and then there's only 1 place to revise the HTML.
When you submit, you get two arrays name "venue_ContactLink_ContactDatas_Type" and "venue_ContactLink_ContactDatas_Data" with matching indicies for the contact pairs, i.e.
venue_ContactLink_ContactDatas_Type[0], venue_ContactLink_ContactDatas_Data[0]
venue_ContactLink_ContactDatas_Type[1], venue_ContactLink_ContactDatas_Data[1]
...
venue_ContactLink_ContactDatas_Type[*n*], venue_ContactLink_ContactDatas_Data[*n*]
Hope that's clear.
So, I have a solution which works in my case, but would need some adjustment if other element types are included, or if other attributes are set by with an index included.
I'll answer my questions in turn:
To select an element which includes square brackets in it's attributes escape the square brackets using double back slashes as follows: var clone = $("#contactFields\[0\]").clone();
& 3. Changing the ids in the tree I have implemented with the following function, where clone is the variable clone (in 1) and count is the count of cloned statements.
function updateAttributes(clone, count) {
var attribute = ['id', 'for', 'name'];
var f = clone.find('*').andSelf();
f.each(function(i){
var tag = $(this);
$.each(attribute, function(i, val){
var s = tag.attr(val);
if (s!=null&& s!="")
{
s = s.replace(/([^\[]+)\[0\]/, "$1["+count+"]");
tag.attr(val, s);
}
});
if ($(this)[0].nodeName == 'SELECT')
{ $(this).val(0);}
else
{
$(this).val("");
}
});
}
This may not be the most efficient way or the best, but it does work in my cases I have used it in. The attributes array could be extended if required, and further elements would need to be included in the defaulting action at the end, e.g. for checkboxes.