Forums

show/hide based on values

grafik 19 Oct, 2012
Hi
i have read this FAQ and i search the forum but i dont understand how i can do this
(i know that i had to do it with javascript, inserted at: code=> load js, but how that js had to look?):

i have:
a checkbox name=more1 id=more1
a input text field name=material1 id=material1
a input text field name=menge1 id=menge1
a input text field name=einheit1 id=einheit1

a checkbox name=more2 id=more2
a input text field name=material2 id=material2
a input text field name=menge2 id=menge2
a input text field name=einheit2 id=einheit2

and so far, till 20

the input fields should only be visible when checkbox is checked, and the checkbox of the value below should only be visible when checkbox above is checked.
for example at the beginning only checkbox 1 is visible, after check that box, the three inputfields with a 1 inside and checkbox 2 are visible, with a klick on checkbox 2, inputfields with 2 inside and checkbox 3 are visible, and so far.

can someone give me additional help, how to solve that.
i have no problem to extend a code for 20rows when i have the code for 1 or better 2rows.

if it is easier all checkboxes could be replaced by a single dropdown with values 1-20.

thanks for any help that i get.

best regards
grafik

Edit: removed not working code
grafik 23 Oct, 2012
is there noone that can help me? 😟
or is the question not clear enough? 🙄

when i would know, how to hide a input textfield, instead of a textarea field (what FAQ describe)
it would help me maybe enough to create the full .js
(when there are my ID/names used, because than i probably know which values are fix an which are depend on ID or name)
GreyHead 23 Oct, 2012
Hi grafik,

I'll get there - I've just been busy today and only the posts with 'short' answers have been done :-(

Bob
grafik 24 Oct, 2012

I'll get there


thank you, Bob
no need to stress yourself, i can wait when i know aswer will come.
and as long as i know that you get there, i have no problem to wait a few days for the answer.
best regards
grafik
GreyHead 24 Oct, 2012
Hi grafik,

Here's a first version. You can see a demo here.

The form has two main elements: a checkbox with the name and id = 'more1'; and a Custom Element element with the code <div id='add_here' ></div>

Then in a Load JS action I have:
var m_count = 1;
window.addEvent('domready', function() {
	$('more1').addEvent('click', addBlock);
});

function addBlock() {
	var div, label, mat, men, ein, more;
	$('more' + m_count).removeEvent('click', addBlock);
	$('more' + m_count).disabled = true;
	div = new Element('div', {
		id: 'matdiv' + m_count
	});
	label = new Element('label', {
		For: 'material' + m_count,
		text: 'Material ' + m_count
	});
	label.inject(div);
	mat = new Element('input', {
		type: 'text',
		name: 'material' + m_count,
		id: 'material' + m_count
	});
	mat.inject(div);
	men = new Element('input', {
		type: 'text',
		name: 'menge' + m_count,
		id: 'menge' + m_count
	});
	men.inject(div);
	ein = new Element('input', {
		type: 'text',
		name: 'einheit' + m_count,
		id: 'einheit' + m_count
	});
	ein.inject(div);
	div.inject($('add_here'));
	// increment counter
	m_count += 1;
	// build checkbox div
	div = new Element('div', {
		id: 'matdiv' + m_count
	});
	label = new Element('label', {
		For: 'more' + m_count,
		text: 'Add material ' + m_count
	});
	label.inject(div);
	more = new Element('input', {
		type: 'checkbox',
		name: 'more' + m_count,
		id: 'more' + m_count
	});
	more.inject(div);
	div.inject($('add_here'));
	$('more' + m_count).addEvent('click', addBlock);
}

This adds two new divs into the add_here div, one with a label and the three inputs and the second with the nect checkbox. The current checkbox is disabled.

Once you've looked I'm sure that you'll find improvements.

Bob
grafik 26 Oct, 2012
Hi Bob
thank you very much 😀
as you assume i began to modify your code, because i began to understand how it works
for now, it looks like that:

    var m_count = 1;
    window.addEvent('domready', function() {
       $('more1').addEvent('click', addBlock);
    });

    function addBlock() {
       var div, label, mat, men, ein, more, matdiv, eindiv, mendiv;
       $('more' + m_count).removeEvent('click', addBlock);
       $('more' + m_count).disabled = true;
       div.dissolve();
       div = new Element('div', {
          id: 'containerdiv' + m_count
       });

       matdiv = new Element('div', {
       class: 'ccms_form_element cfdiv_text label_over multiline_start'
       });
       
       matdiv.inject(div);
       label = new Element('label', {
          For: 'material' + m_count,
          text: 'Beschreibung/Material ' + m_count
       });
       label.inject(matdiv);       
       mat = new Element('input', {
          type: 'text',
          name: 'material' + m_count,
          id: 'material' + m_count,
          size: '45',
          maxlength: '250'
       });
       mat.inject(matdiv);
       eindiv = new Element('div', {
       class: 'ccms_form_element cfdiv_text label_over multiline_add'
       });
       eindiv.inject(div);
       label = new Element('label', {
          For: 'einheit' + m_count,
          text: 'Einheit'
       });
       label.inject(eindiv);         
       ein = new Element('input', {
          type: 'text',
          name: 'einheit' + m_count,
          id: 'einheit' + m_count,
          size: '5',
          maxlength: '25'
       });
       ein.inject(eindiv);
       mendiv = new Element('div', {
       class: 'ccms_form_element cfdiv_text label_over multiline_add'
       });
       mendiv.inject(div);
       label = new Element('label', {
          For: 'menge' + m_count,
          text: 'Menge'
       });
       label.inject(mendiv);         
       men = new Element('input', {
          type: 'text',
          name: 'menge' + m_count,
          id: 'menge' + m_count,
          size: '5',
          maxlength: '50'
       });
       men.inject(mendiv);

       div.inject($('add_here'));
       // increment counter
       m_count += 1;
       // build checkbox div
       div = new Element('div', {
          id: 'containerdiv' + m_count,
          class: 'ccms_form_element cfdiv_checkbox'
       });
       label = new Element('label', {
          For: 'more' + m_count,
          text: 'mehr Material '
       });
       label.inject(div);
       more = new Element('input', {
          type: 'checkbox',
          name: 'more' + m_count,
          id: 'more' + m_count
       });
       if (m_count < 30) {
       more.inject(div);
       div.inject($('add_here'));
       $('more' + m_count).addEvent('click', addBlock);}
    }


did i assume right when i wish to save the values from this inputfields to the DB and also send them to Mail, best way to do it is to limit the count and precreate all db-table-rows and check filled values for mail with php (when i wish to show only filled fields inside the mail)

i think about to modify code even more, that at the end he do this:
click at checkbox1: shows / hide input fields1, and shows/hide checkbox2
click at checkbox2: shows / hide input fields2, and shows/hide checkbox3, hide and disable/shows and enable checkbox1
click at checkbox3: shows / hide input fields3, and shows/hide checkbox4, hide and disable/shows and enable checkbox2
...
GreyHead 27 Oct, 2012
Hi grafik,

did i assume right when i wish to save the values from this inputfields to the DB and also send them to Mail, best way to do it is to limit the count and precreate all db-table-rows and check filled values for mail with php (when i wish to show only filled fields inside the mail)


To take the mail first, I'd use PHP to create that part of the Email template and loop though each of the values in the $form->data array to see if they are used - and only include them in the template if they are.

Database saving is more complicated and depends on how you want to use it. You can either use a PHP loop to extract all the 'set' values and then combine them into a single column using JSONencode or serialise; or you could add each material as a separate record in another table.

The second solution is better if you want to search the database records later.

Bob

PS I couldn't understand exactly how the clicking pattern you suggested works - it is probably possible to set it up. Equally, you could use a single 'Add another row' button.



Bob
grafik 29 Oct, 2012
Hi Bob
thank you for the info and your input about to solve it.

I would like to save values to the DB as if the came from normally input fields, and not created by .js don't know wich of your descripted ways this normally is solved.

Equally, you could use a single 'Add another row' button.


You are absolutely right, because I don't need the value of the checkbox,
is what I wish more like a single checkbox that "add a row (with multiple input-fields)"
and maybe a second checkbox that "delete a row" (but that is optional)
I was not thinking about such a "simple" solution before.

because at the beginning I was thinking about to pre-create all fields and show/hide them afterwards (this was how I saw it at the FAQ and what I find when I search through the forum), not like now to add/create the rows from nowhere, and because of that I had for every row a checkbox.
but maybe inside my mind I was thinking to something similar with "the single dropdown" as alternate to the checkboxes

if it is easier all checkboxes could be replaced by a single dropdown with values 1-20.


for now, it also don't have to be checkboxes, there could be also be two buttons, that do the same.

Edit:
i was able to do it with a button, thanks to your new demo
    var m_count = 1;
window.addEvent('domready', function() {
$('add_row').addEvent('click', function(event) {
form = event.target.getParent('form');
addBlock(form);
});
}); 

    function addBlock() {
       var div, label, mat, men, ein, more, matdiv, eindiv, mendiv;

       div = new Element('div', {
          id: 'containerdiv' + m_count
       });

       matdiv = new Element('div', {
       class: 'ccms_form_element cfdiv_text label_over multiline_start'
       });
       
       matdiv.inject(div);
       label = new Element('label', {
          For: 'material' + m_count,
          text: 'Beschreibung/Material ' + m_count
       });
       label.inject(matdiv);       
       mat = new Element('input', {
          type: 'text',
          name: 'material' + m_count,
          id: 'material' + m_count,
          size: '45',
          maxlength: '250'
       });
       mat.inject(matdiv);
       eindiv = new Element('div', {
       class: 'ccms_form_element cfdiv_text label_over multiline_add'
       });
       eindiv.inject(div);
       label = new Element('label', {
          For: 'einheit' + m_count,
          text: 'Einheit'
       });
       label.inject(eindiv);         
       ein = new Element('input', {
          type: 'text',
          name: 'einheit' + m_count,
          id: 'einheit' + m_count,
          size: '5',
          maxlength: '25'
       });
       ein.inject(eindiv);
       mendiv = new Element('div', {
       class: 'ccms_form_element cfdiv_text label_over multiline_add'
       });
       mendiv.inject(div);
       label = new Element('label', {
          For: 'menge' + m_count,
          text: 'Menge'
       });
       label.inject(mendiv);         
       men = new Element('input', {
          type: 'text',
          name: 'menge' + m_count,
          id: 'menge' + m_count,
          size: '5',
          maxlength: '50'
       });
       men.inject(mendiv);

       div.inject($('add_here'));
       // increment counter
       m_count += 1;
       // build checkbox div
      
       if (m_count > 30) {
       $('add_row').removeEvent('click', addBlock);
       $('add_row').disabled = true;
}
    }

<div id='add_here' ></div><div style="text-align:left" id="add_row_container_div" class="ccms_form_element cfdiv_submit"><input type="button" value="mehr Material" class="" id="add_row" name="add_row">
<div class="clear"></div><div id="error-message-add_row"></div></div>

best regards
grafik
GreyHead 29 Oct, 2012
Hi grafik,

The inputs will return data in exactly the same way as normal ChronoForms inputs. Add a Debugger to the On Submit event to see what is there. I suspect that the biggest problem will be organising the results to save them in a sensible way. At the very least you will need to add a Handle Arrays event but that may not be enough.

I'll look at the 'add a row' code.

Bob
GreyHead 29 Oct, 2012
Hi Grafik,

I re-worked the code into an 'Add a row' format with Delete/Undelete buttons and added validation as well. There's a demo form here. I'll post the code in the morning.

Bob
grafik 30 Oct, 2012
hello, Bob. thanks for the demo.

with this demo and the help of firebug :wink: , i was able to replace my checkbox with a button.
(I began to understand .js better and better, but I still prefer .php 😀 )
i also edit/update my previous post, for the case that someone else read the post, and find it useful.

save data to DB is pretty easy. i dont have to change anything.
(I just have to create table with all fields before. and of course limit the count. like I write/assume inside a previous post)

now i had to bring the email to work like I would.
GreyHead 30 Oct, 2012
Hi grafik,

Well done :-)

For other readers: here is the code I used for the demo form.

The 'Add row' button is a Submit Button element with the type set to regular button and id='add_row'

The JavaScript used in the Load JS action is:
var m_count = 1;
window.addEvent('domready', function() {
	$('add_row').addEvent('click', function(event) {
		form = event.target.getParent('form');
		addBlock(form);
	});
});

function addBlock(form) {
	var div, label, mat, men, ein, del, formCheck;
	// get the validation object
	formCheck = 'formCheck_' + form.get('name');
	formCheck = window[formCheck];
	// add the input elements
	div = new Element('div', {
		id: 'matdiv' + m_count
	});
	label = new Element('label', {
		For: 'material' + m_count,
		text: 'Material ' + m_count
	});
	label.inject(div);
	mat = new Element('input', {
		type: 'text',
		name: 'material' + m_count,
		id: 'material' + m_count,
		Class: "validate['required']"
	});
	formCheck.register(mat);
	mat.inject(div);
	men = new Element('input', {
		type: 'text',
		name: 'menge' + m_count,
		id: 'menge' + m_count,
		Class: "validate['required']"
	});
	formCheck.register(men);
	men.inject(div);
	ein = new Element('input', {
		type: 'text',
		name: 'einheit' + m_count,
		id: 'einheit' + m_count
	});
	ein.inject(div);
	// add a new delete button
	del = new Element('input', {
		type: 'button',
		name: 'del' + m_count,
		id: 'del' + m_count,
		value: 'Delete',
		styles: {
			width: '100px'
		}
	});
	// add a click event to the new delete button
	del.addEvent('click', function(event) {
		delRow(event.target.id, event.target.value);
	});
	del.inject(div);
	div.inject($('add_here'));
	// increment counter
	m_count += 1;
	div.inject($('add_here'));
	// add event to del
}

function delRow(row, value) {
	// get the row number from the button id
	row = row.replace('del', '');
	if(value == 'Delete') {
		// if 'delete' disable all the inputs
		$('material' + row).disabled = true;
		$('menge' + row).disabled = true;
		$('einheit' + row).disabled = true;
		// set the button to 'Undelete'
		$('del' + row).value = 'Undelete';
	} else {
		// enable all the inputs
		$('material' + row).disabled = false;
		$('menge' + row).disabled = false;
		$('einheit' + row).disabled = false;
		// set the button to 'Delete'
		$('del' + row).value = 'Delete';
	}
}

Bob
marklandry 01 Nov, 2012
How can i do this with a checkboxes group?

something like:
if ( checkbox.checked.value == 'Other' ) {

Been trying for about an hour but can't get anything to work.

Thanx for your help

Mark
GreyHead 01 Nov, 2012
Hi Mark,

I'm packing up to go away for the next ten days. You've probably got to get the whole group using $$ then iterate through them to see which one is checked.

Bob
This topic is locked and no more replies can be posted.