Empty controlgroup in jquery mobile - javascript

I am stuck at this point trying to simulate an ajax search box. Take a look a very simple html markup
<div data-role="page" id="lightbox">
<div role="main" class="ui-content">
<div class="ui-field-contain">
<label for="search-input">Seach</label>
<input id="search-input" type="text" name="search" />
</div>
<div class="ui-field-contain">
<label for="results"></label>
<div id="results" data-role="controlgroup" data-input="#search-input"></div>
</div>
</div>
</div>
My intention is to add every "result" as an input radio into the controlgroup. I made it work with the following code:
var counter = 1;
$("#search-input").on("keyup", function (e) {
var $group = $("#results");
var source = ['mark', 'marcus', 'mariah', 'mary']
var value = $(this).val();
// This line is commented because of the problem
//$group.html("");
if (value && value.length > 2) {
$group.controlgroup("refresh");
$.each( source, function ( i, val ) {
var $el = $("<label for='user-" + counter + "'>" + val + "</label><input name='users' id='user-" + counter + "' value='x' type='radio'></input>");
$group.controlgroup("container").append($el);
$( $el[ 1 ] ).checkboxradio();
counter ++;
});
$group.controlgroup("refresh");
}
});
What is the problem? Well, for each keyup event I want to clear/empty the controlgroup in order to remove the appended elements from previous search. If I use $group.html(""); (see the commented code line) the incomming results are not appended. You can see live example at:
http://jsfiddle.net/manix/4rjkermc/3/

You can make use of $group.controlgroup("container").empty(); to empty your group container. see below code and jsfiddle
var counter = 1;
$("#search-input").on("keyup", function (e) {
var $group = $("#results");
var source = ['mark', 'marcus', 'mariah', 'mary']
var value = $(this).val();
// This line is commented because of the problem
//$group.html("");
$group.controlgroup("container").empty();//empty your container
if (value && value.length > 2) {
$group.controlgroup("refresh");
$.each( source, function ( i, val ) {
var $el = $("<label for='user-" + counter + "'>" + val + "</label><input name='users' id='user-" + counter + "' value='x' type='radio'></input>");
$group.controlgroup("container").append($el);
$( $el[ 1 ] ).checkboxradio();
counter ++;
});
$group.controlgroup("refresh");
}
});
JSFiddle Demo

Related

how to serialize a form under specific conditions

Taka a look at this fiddle here this is a form where a business user enters the offered services.I sent the data with ajax and by serializing the form.
Click edit and add(plus sign) a service...in the example an input is added where it's name attribute value is of this **form= form[5]...**contrast with this with the form of the name attribute value in the other inputs...only the newly added services have the name attribute like this and the reason for that is to serialize only these...and not the others already present in the DOM/stored in the DB.
And now my problem:
Imagine that the user goes to edit the already registered services(or that he goes to edit them and add a new one)...at this case the already registered services wont'be serialized cause of the form the name attribute value has...(and the reason for this is explained above).
What can I do in this case?Sometimes I must serialize only part of a form and sometimes whole of the form.If all the inputs have name attribute value of form[1....] then along with the newly added input...already registered services will be serialized again.
Thanks for listening.
Code follows(you can see it in the fiddle too)
$('.editservices').click(function() {
//console.log(('.wrapper_servp').length);
originals_ser_input_lgth = $('.services').length;
var originals = [];
$('.show_price')
// fetch only those sections that have a sub-element with the .value
class
.filter((i, e) => $('.value', e).length === 1)
// replace content in remaining elements
.replaceWith(function(i) {
var value = $('.value', this).data('value');
var fieldsetCount = $('#serv').length;
var index = fieldsetCount + i;
return '<div class="show_price"><p id="show_p_msg">Price
visibility</p></div>' + '\
<div class="show_p_inpts">' +
'<input class="price_show"' + (value == 1 ? "checked" : "") + '
type="radio" name="form[' + index + '][price_show]" value="1">yes' +
'<input class="price_show"' + (value == 0 ? "checked" : "") + '
type="radio" name="form[' + index + '][price_show]" value="0">no' +
'</div>'; // HTML to replace the original content with
});
$('#buttons').removeClass('prfbuttons');
$('#saveserv').addClass('hideb');
$('.actionsserv').removeClass('actionsserv');
priceavail = $(".price_show:input").serializeArray();
});
$('#addser').on('click', function() {
$('#saveserv').css('border','2px solid none');
var serviceCount = $('input.services').length + 1;
var serv_inputs = '<div class="wrapper_servp"><div class="serv_contain">\n\
<input placeholder="service" class="services text" name="form[' + serviceCount + '][service]" type="text" size="40"> \n\
<input placeholder="price" class="price text" name="form[' + serviceCount + '][price]" type="text" size="3"></div>';
var p_show = '<div class="show_p">' +
'<p id="show_p_msg">Price visibility;</p>' +
'<span id="err_show_p"></span><br>' +
'</div>';
var inputs = '<div class="show_p_inpts">' +
'<input class="price_show" type="radio" name="form[' + serviceCount + '][price_show]" value="1">yes' +
'<input class="price_show" type="radio" name="form[' + serviceCount + '][price_show]" value="0">no' +
'</div></div>';
$('.wrapper_servp').last().after(serv_inputs + p_show + inputs);
$('#saveserv').removeClass('hideb');
$('#remser').css('display', 'inline');
});
$('#cancelserv').click(function(e) {
e.preventDefault();
//var newinputs = $('.wrapper_servp').length;
//var inp_remv = newinputs - originals_ser_input_lgth;
//$('.wrapper_servp').slice(-inp_remv).remove()
$('.show_p_inpts')
.filter((i, e) => $('.price_show:checked', e).length === 1)
.replaceWith(function(i) {
var value = $('.price_show:checked').attr('value');
return '<span data-value="' + value + '" class="value">' + (value == 1 ? "yes" : "no") + '</span>'
});
});
var groupHasCheckedBox = function() {
return $(this).find('input').filter(function() {
return $(this).prop('checked');
}).length === 0;
},
inputHasValue = function(index) {
return $(this).val() === '';
};
$('#saveserv').click(function(e) {
e.preventDefault();
//from here
var $radioGroups = $('.show_p_inpts');
$('.show_p_inpts').filter(groupHasCheckedBox).closest('div').addClass("error");
$('.services, .price').filter(inputHasValue).addClass("error");
//to here
var $errorInputs = $('input.services').filter((i, e) => !e.value.trim());
if ($errorInputs.length >= 1) {
console.log($errorInputs);
$('#err_message').html('you have to fill in the service'); return;
}
if ($('input.price').filter((i, e) => !e.value.trim()).length >= 1) {
$('#err_message').html('you have to fill in the price'); return;
}
});
var IDs=new Array();
$('body').on('click', '#remser', function(e){
var inputval=$('.services:visible:last').val();
if(inputval!=='')
{r= confirm('Are you sure you want to delete this service?');}
else
{
$('.wrapper_servp:visible:last').remove();
}
switch(r)
{
case true:
IDs.push($('.services:visible:last').data('service'));
$('.wrapper_servp:visible:last').addClass('btypehide');
if($('.serv_contain').length==1)$('#remser').css('display','none');
$('#saveserv').removeClass('hideb').css('border','5px solid red');
//originals.servrem=true;
break;
case false:var i;
for(i=0;i<originals.ser_input_lgth;i++)
{
$('input[name="service'+i+'"]').val(services[i].value);
$('input[name="price'+i+'"]').val(prices[i].value);//εδω set value
}
$('.services').slice(originals.ser_input_lgth).remove();
$('.price').slice(originals.ser_input_lgth).remove();
$('.openservices').addClass('hide').find('.services,.price').prop('readonly', true);
var text='<p class="show_price">Θες να φαίνεται η τιμή;<span data-value="'+ show_pr_val.value +'" class="value">' +(show_pr_val.value==1 ? 'yes':'no') + '</span></p>';
$('.show_p_inpts').remove();
$('.show_price').replaceWith(text);;
break;
}
});
I have an Idea for you. What you can do is when you show the currently existed value in you html instead of giving name attribute just give data-name attribute. I.e
Change this
<input class="services text" data-service="21" size="40" value="hair" type="text" name="service0" readonly="">
To This
<input class="services text" data-service="21" size="40" value="hair" type="text" data-value="hair" data-name="service0" readonly="">
Now when user update this values you can bind an event in jQuery like below.
$(document).ready(function(){
$(".services input").on("change paste keyup", function() {
if($(this).val() === $(this).attr("data-value"))
{
$(this).removeAttr("name");
}else{
$(this).attr("name",$(this).attr("data-name"));
}
});
});
By this way you can give name attribute to only those elements whose values are changed. Now each time you can serialize the whole form and it will only get the value of changed elements.
Don't forget to give unique class to already existed elements so you can bind on change event. Hope its clear to you.

Disable unchecked check boxes in selected div element using jquery

I am creating check boxes dynamically using jquery. I want to disable unchecked check boxes as shown in the snippet,but i want to disable the check boxes only in their respective div elements and not in the other div elements which is what causing issue now.
I have written the code to disable/enable checkboxes based on their respective div tags and i have commented it as it is throwing error if enabled.
$($(".checkbox").eq(id).":checkbox[name='radio']:not(:checked)").prop('disabled', true);
Problem explanation : Here i am creating two div tags dynamically inside which check boxes are also created with same name. So if i check on checkbox in first div other checkbox gets disabled and other div tag gets created which works as expected. but if i check any option in second div tag other option in second div tag doesn't get disabled and also if i uncheck the checked option in first div tag both options get disabled in first div tag. I guess this is because all checkboxes have same names.
How can we disable checkboxes only in their respective div tags. I tried below code but didn't work
$($(".checkbox").eq(1).":checkbox[name='radio']:not(:checked)").prop('disabled', true);
Below snippet explains the problem more appropriately
Please help me.
function checkdiv(id, val) {
if ($(":checkbox[name='radio']:checked").length == 1)
$(":checkbox[name='radio']:not(:checked)").prop('disabled', true);
else
$(":checkbox[name='radio']:not(:checked)").prop('disabled', false);
var diva = Number(id) + 1;
var divb = Number(id) + 1;
//if(id.length != 0){
if (val.checked == true) {
if (diva < 2 && divb < 2) {
creatediv('maindiv')
}
}
// }
else {
var diva = Number(id) + 1;
var divb = Number(id) + 1;
$("#" + diva).remove();
$(".divot").eq(divb).remove();
}
}
function creatediv(main) {
var divid = $(".divin").length;
var divid1 = $(".divot").length;
var div = "<div class='col-xs-2 divin' id='" + divid + "' style='border:1px solid'><span class='header'></span></div><div class='col-xs-1 divot'></div>";
$('#' + main).append(div);
loadval(divid)
}
function loadval(div) {
var div1 = "<div class='checkbox'><label><input type='checkbox' name='radio' value='Head' onchange='checkdiv(" + div + ",this)'>Head</label><br><label><input type='checkbox' name='radio' value='Hand' onchange='checkdiv(" + div + ",this)'>Hand</label></div>";
$("#" + div).append(div1)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body onload="creatediv('maindiv')">
<div class="container">
<div class="form-group row" id="maindiv">
</div>
</div>
</body>
Have you tried ".find" in the jQuery API - this will only find elements within the specified selector - see the modifications to the "checkdiv" function ($('#' + id))
function checkdiv(id, val) {
if ($('#' + id).find(":checkbox[name='radio']:checked").length == 1)
$('#' + id).find(":checkbox[name='radio']:not(:checked)").prop('disabled', true);
else
$('#' + id).find(":checkbox[name='radio']:not(:checked)").prop('disabled', false);
var diva = Number(id) + 1;
var divb = Number(id) + 1;
//if(id.length != 0){
if (val.checked == true) {
if (diva < 2 && divb < 2) {
creatediv('maindiv')
}
}
// }
else {
var diva = Number(id) + 1;
var divb = Number(id) + 1;
$("#" + diva).remove();
$(".divot").eq(divb).remove();
}
}
function creatediv(main) {
var divid = $(".divin").length;
var divid1 = $(".divot").length;
var div = "<div class='col-xs-2 divin' id='" + divid + "' style='border:1px solid'><span class='header'></span></div><div class='col-xs-1 divot'></div>";
$('#' + main).append(div);
loadval(divid)
}
function loadval(div) {
var div1 = "<div class='checkbox'><label><input type='checkbox' name='radio' value='Head' onchange='checkdiv(" + div + ",this)'>Head</label><br><label><input type='checkbox' name='radio' value='Hand' onchange='checkdiv(" + div + ",this)'>Hand</label></div>";
$("#" + div).append(div1)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body onload="creatediv('maindiv')">
<div class="container">
<div class="form-group row" id="maindiv">
</div>
</div>
</body>

Check all or uncheck all in multi checkbox

I have this code for multi check-box
HTML:
<fieldset data-role="collapsible">
<legend>Pick one</legend>
<div data-role="controlgroup" id="ZIBI" align="right" >
</div>
</fieldset>
jQuery/JavaScript:
myArray1 = new Array(
"1","2","3","4","5","6"
);
$("#ZIBI").html('');
for (var i = 0; i < myArray1.length; i++) {
row = myArray1[i];
$("#ZIBI").append(
'<label for=' + row + '>' + row + '</label>' +
'<input type="checkbox" name="favcolor" id=' + row + ' value=' + row + '>');
}
$('#ZIBI').trigger('create');
how to check all or uncheck all by pressing any button ?
thanks
In this JsFiddle you'll find a method to check/uncheck all checkboxes within a given div, using a checkbox with id _main:
function checkAll(e){
e = e || event;
var from = e.target || e.srcElement
,cbs = this.querySelectorAll('input'), i=1;
if (/^_main$/i.test(from.id)){
for (;i<cbs.length;i+=1){
cbs[i].checked = from.checked;
}
} else {
var main = document.querySelector('#_main')
,j = cbs.length;
for (;i<cbs.length;i+=1){
j -= cbs[i].checked ? 0 : 1;
}
main.checked = j === cbs.length ? true : false;
}
}
Update
New elements should be added to $(".selector").controlgroup("container") not $(".selector") directly. If you add them to main div, elements won't be styled as a _controlgroup`.
You need to refresh .checkboxradio("refresh") checkbox or radio to apply jQM styles. Another point, .trigger("create") is deprecated as of jQM 1.4 and replaced with .enhanceWithin().
myArray1 = new Array(
"1", "2", "3", "4", "5", "6");
/* remove previous elements */
$("#ZIBI").controlgroup("container").html('');
for (var i = 0; i < myArray1.length; i++) {
row = myArray1[i];
/* add new ones to container */
$("#ZIBI").controlgroup("container").append(
'<label for=' + row + '>' + row + '</label>' +
'<input type="checkbox" name="favcolor" id=' + row + ' value=' + row + '>');
}
/* refresh controlgroup and enhance elements within */
$("#ZIBI").controlgroup().enhanceWithin();
/* check/uncheck on button click */
$("#foo").on("click", function () {
var status = $("#ZIBI [type=checkbox]").eq(0).prop("checked") ? false : true;
$("#ZIBI [type=checkbox]").prop("checked", status).checkboxradio("refresh");
});
Demo
You can try this:
HTML:
<fieldset data-role="collapsible">
<legend>Pick one</legend>
<div data-role="controlgroup" id="ZIBI" align="right" >
</div>
</fieldset>
<input type="checkbox" id="all" value="Toggle" />
jQuery:
$('#all').on('click', function() {
if(this.checked) {
$('#ZIBI').find('input[type=checkbox]').prop('checked', true);
} else {
$('#ZIBI').find('input[type=checkbox]').prop('checked', false);
}
});
Working Fiddle.

Build a array of div's id using each DIV inside section

I'm trying to get the ID of each DIV inside this HTML code
<section id="choices">
<div id="talla_choice_24" style="">
...
</div>
<div id="color_choice_25" style="">
...
</div>
<div id="sport_choice_26" style="">
...
</div>
<button type="button" class="create-variation" id="create-variation" style="">Crear variaciones</button>
<section id="variations_holder" style="display: none"></section>
</section>
So I made this:
function getDivId(div) {
var inputValues = [];
$("#" + div + ' > div').each(function() {
inputValues.push($(this).val());
})
return inputValues;
}
And I call here:
$('#choices').on("click", "#create-variation", function(e) {
var parent_id = $(this).closest("section").attr("id");
var element = getDivId(parent_id);
iterateChoices("", element[0], element.slice(1), 0);
});
I need to build something like this:
var element = new Array($('#talla_choice_24 input:text'), $('#color_choice_25 input:text'), $('#sport_choice_26 input:text'));
But I get this error:
Uncaught TypeError: Object has no method 'each'
What is wrong?
UPDATE
This is the code for iterateChoices() function:
function iterateChoices(row, element, choices, counter) {
if ($.isArray(choices) && choices.length > 0) {
element.each(function(index, item) {
if (counter == 0)
row = '<input type="text" required="required" value="" name="pupc[]" /><input type="text" required="required" value="" name="pprice[]" /><input type="text" required="required" value="" name="pqty[]" />';
iterateChoices(row + '<input value="' + item.value + '">', choices[0], choices.slice(1), counter + 1);
});
} else {
html_temp = "";
$.each(element, function(index, item) {
html_temp += row + '<input value="' + item.value + '"><br>';
});
html += html_temp;
}
}
I also made some changes at this code:
function getDivId(div) {
var inputValues = [];
$("#" + div + ' > div').each(function() {
inputValues.push("#" + $(this).attr('id') + ' input:text');
});
return inputValues;
}
And now the error change to this:
Uncaught TypeError: Object #talla_choice_24 input:text has no method 'each'
UPDATE 2
I still continue change getDivId() function to build a array like this:
var element = new Array($('#talla_choice_24 input:text'), $('#color_choice_25 input:text'), $('#number_choice_23 input:text'), $('#sport_choice_23 input:text'));
But can't get it since array values are constructed as strings, see below:
function getDivId(div) {
var inputValues = [];
$("#" + div + ' > div').each(function() {
inputValues.push('$("#' + $(this).attr('id') + ' input:text")');
});
return inputValues;
}
I'm getting:
("$('#talla_choice_24 input:text')", "$('#color_choice_25 input:text')")
I think there is the problem
You are using the val method on a div element, which just returns an empty string. There is no each method on a string.
You don't need the id of each div to get the input elements inside them. This will get you the inputs in a single jQuery object:
var element = $(this).closest("section").find("> div input:text");
If you really need an array of separate jQuery objects, you can then do this:
element = element.map(function(){ return $(this); }).get();
var arr = [];
$("#create-variation").on('click', function(){
$("#choices > div").each(function(a,b){
arr.push($(this).text());
});
});
After some headaches I realized how to fix the (my) error, here is the solution to all the problems:
function getDivId(div) {
var inputValues = [];
$("#" + div + ' > div').each(function() {
inputValues.push($("#" + $(this).attr('id') + " input:text"));
});
return inputValues;
}

How do I define a variable and call it in a hidden input field?

I have a javascript code that does some math and I need to be able to just pull the final result and include it in a form. To do that I wanted to just use a <input type="hidden" name="new total">. I want to grab the results from the field "New Total". You can see my javascript code in action here. http://jsfiddle.net/danielrbuchanan/yjrTZ/5/
var prices = [];
function remove(arr,itm){
var indx = arr.indexOf(itm);
if (indx !== -1){
arr.splice(indx,1);
}
}
function calculateSectedDues(checkbox, amount) {
if (checkbox.checked === true) {
prices.push(amount);
} else {
remove(prices, amount);
}
var total = 0;
for (var i = 0, len = prices.length; i < len; i++)
total += prices[i];
var min = prices.slice().sort(function(a,b){return a-b})[0];
if(typeof min === 'undefined') min = 0;
var withDiscount = total - min;
var discountAmount = withDiscount - total;
//document.grad_enroll_form.total.value = total;
document.querySelector("#value").innerHTML = "Total: $"+total+'<br>';
document.querySelector("#value").innerHTML += "Discount: $"+discountAmount+'<br>';
document.querySelector("#value").innerHTML += "New total: $"+withDiscount+'<br>';
}
It seems simple, for some reason I'm drawing a blank on how to do it.
What i think you want is to set an input value with your variable, so i think it should go like this:
Javascript:
document.getElementById("newTotal").value = your_new_total;
HTML:
<form>
<input id='newTotal' type='hidden' name='NewTotal' value='' />
</form>
Hope this helps.
<input type="hidden" id="new_total" name="new_total">
<!-- no spaces in name and id -->
Put this code at end of the calculateSectedDues function
document.getElementById('new_total').value = withDiscount
You have a couple of options.
Option 1:
jQuery
Add a visible div, how ever you want to do things.
Bind onChange() events to your input fields that drive the calculation.
<div id="finalValue"></div>
<script language="javascript">
$(function() {
$("form input").change(function() {
calculateSectedDues($("#checkboxid"), $("#amountid").val());
});
});
</script>
In the calculateSectedDues() function add this to the end:
$("#finalValue").html("Total: $" + total + "<br />Discount: " + discountAmount + "<br />New Total: " + withDiscount + "<br />");
Option 2:
No jQuery
<div id="finalValue"></div>
<script language="javascript">
function bindEvent() {
calculateSectedDues(document.getElementById("checkboxid"), document.getElementById("amountid").value);
}
window.onload = function()
{
var elJ = document.getElementsByTagName("input");
for (var i=0;i<elJ.length;i++) {
elJ[i].addEventListener('change',bindEvent,false);
}
}
</script>
In the calculateSectedDues() function add this to the end:
document.getElementById("finalValue").InnerHtml("Total: $" + total + "<br />Discount: " + discountAmount + "<br />New Total: " + withDiscount + "<br />");
Is that what you are trying to get after?
You should also remember to do the calculation on the Server Side too and not rely on the JavaScript to do it for you. This would simply be to notify the user what they are getting before hand. Otherwise, front-end hacks could easily be done if you are using a hidden total field.

Categories

Resources