String variable unrecognized in Jquery Selector - javascript

I'm using Bootstrap Switch
to customize my checkboxes. In the documentation they suggest using:
$("[name='my-checkbox']").bootstrapSwitch();
So in my case I have multiple checkboxes so I did this:
var name = '"' + "[name='my-checkbox" + records[i].id + "']" + '"';
$(name).bootstrapSwitch();
But I get an error: Unrecognized expression: "[name='my-checkbox1']"

Remove extra "
var name = '[name="my-checkbox' + records[i].id + '"]';
Example
var records = [
{id: '-one'},
{id: '-two'}
];
var name;
for (var i = 0, len = records.length; i < len; i++) {
name = '[name="my-checkbox' + records[i].id + '"]';
console.log($(name));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input name="my-checkbox-one" type="checkbox">
<input name="my-checkbox-two" type="checkbox">

You do not need that much coding... If you add a class to you checkbox <input name="my-checkbox" class="nice-switch" type="checkbox">you can then activate the switch using $(".nice-switch").bootstrapSwitch();

Related

Javascript: how get all the values and id from an inputs array?

So I'm trying to get all the values and id of every input from an array, but I have an issue, the user can duplicate the input and each input have a randomly generated ID so I can't select the data with the ID and every input use name="cate[]" so every input have the same name, so I can use something like this:
function regTour() {
var input = document.getElementsByName('cat[]');
var k = "The respective values are :";
for (var i = 0; i < input.length; i++) {
var a = input[i];
k = k + "array[" + i + "].value= "
+ a.value + " ";
}
console.log('Console: ' + k);
}
but how I can get the ID from every input from the array paired with the input value?
Edit: -------------------
the input looks like this:
<input type="text" id="1666239497429" name="cat[]" class="form-control">
<input type="text" id="12983172462" name="cat[]" class="form-control">
<input type="text" id="812361647812" name="cat[]" class="form-control">
this input it's created dynamically by the user so the id changes, this id later it's stored with other sub fields that should be related with that id, that's why it's some kind important for me be able to store all the id's
You can get the id of DOM elements using the id property. From your example, just use a.id to access it.
Side note, you should use const instead of var if the variable is not going to be changed, and let if it does change. var shouldn't be used any more.
function regTour() {
var input = document.getElementsByName('cat[]');
var k = "The respective values are :";
for (var i = 0; i < input.length; i++) {
var a = input[i];
k = k + "array[" + i + "].value= "
+ a.value + " array[" + i + "].id= " + a.id;
}
console.log('Console: ' + k);
}
can you share more data from the front? how is your form?
This ist OK var input = document.getElementsByName('cat[]'); but I'm not sure what the problem is

Number of class element

i can have many elements within one class for example:
<input class='example' id='one' ...onclick="setURL(urls[0])"
<input class='example' id='two' ...onclick="setURL(urls[1])"
<input class='example' id='three' ...onclick="setURL(urls[2])"
....
urls[] is an array with strings to different html pages.
if i write something like:
var all = document.getElementByClassName('example');
all.length is then 2. Is there any possibility to transfer the number from the var all into the from the vector urls[]?
Something like this:
<input class='example' id='one' ...onclick="setURL(this.all)"
Wouldn't it be better to generate the HTML itself within a loop in your javascript code? that way you should have more option to do what you want?
something like this, for instance:
https://codepen.io/anon/pen/ybqzoy
(function() {
var i, key, len, list, t, val;
list = ['one', 'two', 'three'];
for (key = i = 0, len = list.length; i < len; key = ++i) {if (window.CP.shouldStopExecution(1)){break;}
val = list[key];
t = "<div class='example' id='" + val + "' onClick='setUrl(urls[" + key + "])'>" + val + "</div>";
$('#res').append(t);
console.log("t is " + t);
}
window.CP.exitedLoop(1);
}).call(this);

Counting form fields using js

I have the form that looks like this:
<form method="post" action="">
<label for="id_count-count">Count:</label>
<input id="id_count-count" type="number" name="count-count">
<div class="extrafieldWrapper"></div>
<input type="submit" value="Submit">
</form>
Depending on number of field count i add or delete new couple of fields item and item2. For example: if value of field count will be 2, it will generate two couples of fields item and item2.
There is this fields:
<label for="id_items-0-item">Item:</label>
<input id="id_items-0-item" type="number" name="items-0-item">
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="0">
<div class="extrafieldWrapperChAge"></div>
Then, depending on each value of field item2 i add new fields that calls childrenage. There is how looks childrenage field:
<label for="id_childrenage-0-childrenage">ChildrenAge 1</label>
<input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">
Here is fiddle link .
And here is imgur of what i want and what i've got link.
Depending of value of item2 the id of childrenage is changing too. For example if i have '3' as value of item2, then i have id_childrenage-0-childrenage, id_childrenage-1-childrenage and id_childrenage-2-childrenage. And if i have several item2 i have new examples of childrenage that count their id from the start for each item2:
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="2">
<div class="extrafieldWrapperChAge">
<label for="id_childrenage-0-childrenage">ChildrenAge</label>
<input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">
<label for="id_childrenage-1-childrenage">ChildrenAge</label>
<input id="id_childrenage-1-childrenage" type="number" name="childrenage-1-childrenage" value="0">
</div>
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="1">
<div class="extrafieldWrapperChAge">
<label for="id_childrenage-0-childrenage">ChildrenAge</label>
<input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">
</div>
In example above i have 2 fields item2, on one of it value '2' and on another value '1'. According to this i have two fields of childrenage for the first item2 with id id_childrenage-0-childrenage and id_childrenage-1-childrenage, and one field childrenage for the second with id id_childrenage-0-childrenage. But i need that count of id childrenage go on from the first item2 to the last, this is example:
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="2">
<div class="extrafieldWrapperChAge">
<label for="id_childrenage-0-childrenage">ChildrenAge</label>
<input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">
<label for="id_childrenage-1-childrenage">ChildrenAge</label>
<input id="id_childrenage-1-childrenage" type="number" name="childrenage-1-childrenage" value="0">
</div>
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="1">
<div class="extrafieldWrapperChAge">
<label for="id_childrenage-2-childrenage">ChildrenAge</label>
<input id="id_childrenage-2-childrenage" type="number" name="childrenage-2-childrenage" value="0">
</div>
Here is js code that realize this:
$(function(){
$('#id_count-count').on('change', function(e){
var n = $('#id_count-count').val() || 0;
var html = "<input id='id_items-TOTAL_FORMS' type='hidden' value='" + n + "' name='items-TOTAL_FORMS'>"
+ "<input id='id_items-INITIAL_FORMS' type='hidden' value='0' name='items-INITIAL_FORMS'>"
+ "<input id='id_items-MIN_NUM_FORMS' type='hidden' value='0' name='items-MIN_NUM_FORMS'>"
+ "<input id='id_items-MAX_NUM_FORMS' type='hidden' value='15' name='items-MAX_NUM_FORMS'>";
for (var i = 0; i < n; i++) {
html += "<div>Items" + (i + 1) + "</div>"
+ "<br/><label for='id_items-" + i + "-item'>Item:</label>"
+ "<input id='id_items-" + i + "-item' type='number' name='items-" + i + "-item'/>"
+ "<label for='id_items-" + i + "-item2'>Item2:</label>"
+ "<input id='id_items-" + i + "-item2' type='number' value='0' name='items-" + i + "-item2' class='children_age'/>"
+ "<div class='extrafieldWrapperChAge'></div>";
}
$(".extrafieldWrapper").html(html);
});
$(".extrafieldWrapper").on('change', '.children_age', function(e){
var n = $(this).val() || 0;
var html = "<input id='id_childrenage-TOTAL_FORMS' type='hidden' value='" + n + "' name='childrenage-TOTAL_FORMS'>"
+ "<input id='id_childrenage-INITIAL_FORMS' type='hidden' value='0' name='childrenage-INITIAL_FORMS'>"
+ "<input id='id_childrenage-MIN_NUM_FORMS' type='hidden' value='0' name='childrenage-MIN_NUM_FORMS'>"
+ "<input id='id_childrenage-MAX_NUM_FORMS' type='hidden' value='15' name='childrenage-MAX_NUM_FORMS'>";
for (var i = 0; i < n; i++) {
html += "<br/><label for='id_childrenage-" + i + "-childrenage'>ChildrenAge "+(i+1)+"</label>"
+ "<input id='id_childrenage-" + i + "-childrenage' type='number' value='0' name='childrenage-" + i + "-childrenage' />";
}
$(this).next('.extrafieldWrapperChAge').html(html);
});
});
Hope you you understand what i mean.
I am newbie in java-script, can you help me to write the code in the right way. Thanks a lot!
This particular answer was getting needlessly long, so I've decided to truncate it to just the current answer.
The Code
$(function() {
var fieldset = $('<fieldset>');
var legend = $('<legend>');
var input = $('<input>').prop('type', 'number');
var hidden = $('<input>').prop('type', 'hidden');
var label = $('<label>');
var child_wrapper = $('<div class="child-wrapper">');
/*
Here we create a couple of new HTML elements. These elements are not a part of the
HTML DOM yet and can therefore be manipulated without any visual changes.
*/
var create_hidden_fields = function(str, fields_arr) {
var ret = [];
//return array;
$.each(fields_arr, function(i, obj) {
//Loops through each field to set up the hidden values
var h = hidden.clone();
//Clones the hidden fields
h.prop('id', 'id_' + str + '-' + obj.name).prop('name', str + '-' + obj.name).val(obj.value);
//Sets the ID, name, and value.
ret.push(h);
});
return ret;
};
$('#id_count-count').on('change', function(e) {
var n = $(this).val() || 0;
//Gets the id count value, or 0;
var hidden_fields = [{
name: 'TOTAL_FORMS',
value: n
}, {
name: 'INITIAL_FORMS',
value: 0
}, {
name: 'MIN_NUM_FORMS',
value: 0
}, {
name: 'MAX_NUM_FORMS',
value: 15
}];
//Hidden fields pre-build, makes life easier, since there seems to be a pattern
var h_arr = create_hidden_fields('items', hidden_fields);
//Hidden Array created
if ($(this.form).children(':hidden')) {
$(this.form).children(':hidden').remove();
//Removes all the current hidden fields, because lazy.
}
$(this.form).prepend(h_arr); //adds in our created hidden fields.
var form = $(this.form).children('.extra-field-wrapper');
//Gets the fieldset wrapper.
form.empty();
//Empties any children there already. Otherwise extra children are added.
for (var i = 0; i < n; i++) {
var fs_clone = fieldset.clone(); //clones the fieldset element
var l_clone = legend.clone().text("Item " + (i + 1));
// clones the legend element and adds text
var la_clone_1 = label.clone();
//label clone 1
var input_clone_1 = input.clone();
//Input clone 1
var child_wrapper_clone = child_wrapper.clone().prop('id', 'parent-' + (1 + i));
//We use clones to keep our initial values safe. This way we can alter the clones without changing our defaults
fs_clone.append(l_clone);
//Adds our legend up top for readability;
la_clone_1.prop('for', 'id-items-' + i + '-item').html('Parent ' + (i + 1));
//Adds the 'for' property with the correct ID, then sets the HTML. Item and Item2 were getting confusing
input_clone_1.prop('value', 0).prop('id', 'id-items-' + i + '-item');
//Sets the default value to 0, and the necessary ID for our label to work
var la_clone_2 = label.clone().html('# of Children').prop('for', 'id-items-' + i + '-num-children');
/*
This is a lot in one line, it clones the label element, adds the HTML, and sets the property all in one.
*/
var input_clone_2 = input.clone().prop('id', 'id-items-' + i + '-num-children').prop('value', 0).addClass('children_age');
//See above comment. One difference is that this adds our class for our next function to work
fs_clone.append([la_clone_1, input_clone_1, la_clone_2, input_clone_2, child_wrapper_clone]);
//This could probably be cleaned up, but for now it works.
form.append(fs_clone); //adds the fieldset clone to the form.
} //End for
});
$(".extra-field-wrapper").on('change', '.children_age', function(e) {
var n = $(this).val() || 0;
// the current value of the item
var append_array = [];
//Add an HTML append array, lessens calls to the $(this).next().append();
$(this).before(h_arr);
//Adds the hidden elements before this element
$(this).next('.child-wrapper').empty();
//Clears the child elements
for (var i = 0; i < n; i++) {
var l_clone = label.clone().html('Children Age' + (i + 1));
var i_clone = input.clone().addClass('child-age').prop('value', 0);
append_array.push(l_clone);
append_array.push(i_clone);
//Adds the elements to the append_array since we are now done with them.
}
$(this).next('.child-wrapper').append(append_array);
//Adds all created elements;
var children_age = $('input.child-age').each(function(i, el) {
var self = $(el);
//Lazy handle
var label = $(el).prev();
//The label is the element in front of our current element.
label.text("Child Age " + (i + 1)).prop('for', 'id_childrenage_' + i + '_childrenage');
//Gives correct label number /re does the for property;
self.prop('id', 'id_childrenage_' + i + '_childrenage');
//give correct id now that changes have been made to the dom.
});
var hidden_fields = [{
name: 'TOTAL_FORMS',
value: children_age.length
}, {
name: 'INITIAL_FORMS',
value: 0
}, {
name: 'MIN_NUM_FORMS',
value: 0
}, {
name: 'MAX_NUM_FORMS',
value: 15
}];
//We have to redeclare this function here in order for the value: n to work correctly.
if ($('#id_childrenage-TOTAL_FORMS').length == 0) {
//This element does not exist yet in the DOM
var hidden_fields = [{
name: 'TOTAL_FORMS',
value: children_age.length
}, {
name: 'INITIAL_FORMS',
value: 0
}, {
name: 'MIN_NUM_FORMS',
value: 0
}, {
name: 'MAX_NUM_FORMS',
value: 15
}];
//We have to redeclare this function here in order for the value: n to work correctly.
var h_arr = create_hidden_fields('childrenage', hidden_fields);
//creates the hidden fields
$(this.form).prepend(h_arr);
} else {
$('#id_childrenage-TOTAL_FORMS').val(children_age.length);
}
});
});
label {
font-weight: 800;
}
input[type="number"] {
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post" action="">
<label for="id_count-count">Count:</label>
<input id="id_count-count" type="number" name="count-count">
<div class="extra-field-wrapper"></div>
<input type="submit" value="Submit">
</form>
The Explanation
I did a few things here, and there is more than likely a better way, but I did the best with my own time constraints.
I create the items to copy into the with jQuery because I'm old school and I just do not remember anything about how the template tag works so I stay away from it's particular variety of magics. The fieldset and legend are there solely for readability. In your actual code you can just delete their references as well as fs_clone and l_clone, instead attach the items directly to the form element.
I created a function that exists solely within the realm of our wrapping anonymous function called create_hidden_fields, as a programmer, mathematician, and all around lazy person I noticed the pattern in the naming convention and this appealed to me more than having to create and copy a bunch of items by hand every time I wanted to create a field.
I have the id_childrenage-TOTAL_FORMS (which is, by the way, the weirdest naming convention I've ever come across) to the form itself. Since we don't need more than 1 copy of the input.
The reason the hidden_fields array is redeclared in both functions is fairly simple: if it is declared before the variable n is, the TOTAL_FORMS input won't have the correct value. Not good.
Hopefully everything else can be answered by my comments in the code itself.
Happy Coding.

Dynamically creating vertically grouped radio buttons with jQuery

I'm dynamically creating several vertically grouped radio buttons using jQuery mobile 1.0 for a multiple choice quiz.
When I paste this code from the JQM Radio Button Docs in it styles the controlgroup properly.
<fieldset data-role="controlgroup">
<input type="radio" name="radio-choice-1" id="radio-choice-1" value="choice-1" checked="checked" />
<label for="radio-choice-1">Cat</label>
<input type="radio" name="radio-choice-1" id="radio-choice-2" value="choice-2" />
<label for="radio-choice-2">Dog</label>
</fieldset>
When I dynamically inject my markup on pageshow() it injects the proper markup but it doesn't style the control group at all.
$.getJSON("assets/json/aircraft.json", function (data) {
var maxQuestions = 10;
var maxChoices = 4;
var randomsorted = data.aircraft.sort(function (a, b) {
return 0.5 - Math.random();
});
var quiz = $.grep(randomsorted, function (item, i) {
return i < (maxQuestions * maxChoices);
});
var arr_quiz_markup = [];
$.each(quiz, function (i, item) {
var q = Math.floor(i / maxChoices);
var c = i % maxChoices;
if (c == 0) arr_quiz_markup.push("<div>Image for question " + q + " goes here...</div><fieldset data-role='controlgroup' data-question='" + q + "'>");
arr_quiz_markup.push("<input type='radio' name='q" + q + "' id='q" + q + "c" + c + "' data-aircraftid='" + item.id + "' />");
arr_quiz_markup.push("<label for='q" + q + "c" + c + "'>" + item.name + "</label>");
if (c == maxChoices - 1 || c == quiz.length - 1) arr_quiz_markup.push("</fieldset><br />");
});
$("#questions").html(arr_quiz_markup.join("")).controlgroup("refresh");
});
I tried $("#questions :radio").checkboxradio("refresh"); but throws "cannot call methods on checkboxradio prior to initialization; attempted to call method 'refresh'".
My Live Quiz Demo (Sorry, jsfiddle doesn't have jQuery Mobile listed)
What am I doing wrong? How do I refresh this to properly get JQM to style the controlgroup correctly?
Add this line
$("#quiz").trigger("create");
after
$("#questions").html(arr_quiz_markup.join("")).controlgroup("refresh");
This code snippet will force a rebuild of the quiz page so that jqm styles will be applied to the page contents.
You will get more information about the dynamic in this jQuery Forum thread.
The jQuery Mobile default styles will be applied once you use the following code. That's what I found and it's working for me.
$("input[type='radio']").checkboxradio().checkboxradio("refresh");
This works for me (I'm using jQuery Mobile 1.4.0):
HTML
<div id="locations" data-role="controlgroup"></div>
JS
$.ajax({
...
success: function(data, textStatus, jqXHR) {
// Hide loading message
$.mobile.loading("hide");
// Build page
$("#location-page").trigger("create");
// Clear another previos radio options
$("#locations").controlgroup("container")["empty"]();
// Read XML response
var rows = $("Row", data);
$(rows).each(function(index, value) {
var locationId = $("LocationID", this).text();
var locationName = $("LocationName", this).text();
var $el = $("<label for=\"location" + index + "\">" + locationName + "</label><input type=\"radio\" name=\"location\" id=\"location" + index + "\" value=\"" + locationId + "\">")
$("#locations").controlgroup("container")["append"]($el);
$($el[1]).checkboxradio();
});
$("#locations").controlgroup("refresh");
// Change to locations' page
$.mobile.changePage("#location-page", {transition: "flip"});
},
...
});

How would I set focus on an after I remove its sibling in javascripts

I have the following code:
remove: function(child, obj){
for (var i = 0, len = obj.compareComponents.length; i < len; i++) {
if (obj.compareComponents[i] == child) {
obj.compareComponents.splice(i, 1);
break;
}
}
dojo.forEach(obj.checks, function(arr){
if (arr.number == child.id) {
obj.states.checkMarks.empty(arr, obj, child);
}
});
obj.properties.numberTaken--;
obj.states.compare.checksFull.value.isTrue = false;
obj.states.compare.checksFull.settings(obj);
if (obj.properties.numberTaken < 2) {
obj.states.compare.noChecks(obj);
}
}
What I am trying to as the checkboxes are unchecked and removed I want the focus to be set on the element to the right of it. What logic do I add to accomplish this?
Focus will set automatically if I can set the tab index of the first checkbox to 0 here is the code that was written creating the check boxes how would I modify it to set the first element's tab index to 0?
var image = arr.image[0].src;
image = '<th id="cell4' + arr.id + '" scope="col"><span class="pcChecks"><input checked="checked" type="checkbox" name="pc' + arr.id + '" id="pc' + arr.id + '" class="compare" /><label for="pc' + arr.id + '" id="" class="compare">' + '<span class="hide-fromsighted">Remove ' + temptitle + '</span>' + 'Remove</label></span><div><img height="106" alt="' + temptitle + '"src="' + image + '"/></div></th>'
If all your checkboxes are the children of the same parent, then in jQuery, I'd use $(obj).next().focus().
I couldn't find a similar API in dojo :-( Which means you'll have to get the children, search yourself and then select the child with index+1.

Categories