I'm trying to build a drop menu where the content is filled with data from a database. I have this working in plain html/jquery, but it doesn't work in a Google apps script.
Code :
function buildDropDown(inTitle, inName, inMenuId, inFilterId, inArray)
{
// Create the drop down menu
var div = $('<div id="' + inMenuId + '" class="funnelFiltermenu">');
var input = $('<input type="text" name="' + inName + '" value="All" class="field" readonly />').appendTo(div);
var ul = $('<ul class="funnelFilterlist">').appendTo(div);
// Add the items of the drop down menu
$.each(inArray, function(index,item) {
$(ul).append('<li>'+item+'</li>')
});
// Add the drop down menu to the funnel
$( div).appendTo(".dropdown");
}
This works outside of Google script. It does not work in the Google apps script. I guess this has something to do with the caja stuff. So I changed the code so it would look for classes which then looks like:
function buildDropDown(inTitle, inName, inMenuId, inFilterId, inArray)
{
// Create the drop down menu
var div = $('<div id="' + inMenuId + '" class="funnelFiltermenu">');
$( div).appendTo(".dropdown");
var theId = app.getElementById(div);
var input = $('<input type="text" name="' + inName + '" value="All" class="field" readonly />').appendTo(theId);
var ul = $('<ul class="funnelFilterlist">').appendTo(".funnelFiltermenu");
// Add the items of the drop down menu
$.each(inArray, function(index,item) {
$(".funnelFilterlist").append('<li>'+item+'</li>')
});
}
Since there will be more than one drop down (with the same classes), I cannot use classes. I'll have to use Ids instead. But caja changes the Id.
Any thoughts on how to approach this?
I have created the following work around:
I hard coded more elements in the html code:
<div class="SSCheader"><h1>Project Eigenschappen</h1></div>
<div class="SSCcontent">
<table>
<tbody>
<tr>
<td><b>Project Nr</b></td>
<td><?= getProjectData(2, 1) ?></td>
</tr>
<tr>
<td><b>Project Initiatief</b></td>
<td>
<div id="dropdown2" class="dropdown">
<div id="dd2" class="funnelFiltermenu">
<input type="text" name="aansturing" value="<?= getProjectData(2, 5) ?>" class="field" readonly />
<ul id="ul2" class="funnelFilterlist"></ul>
</div>
</div>
</td>
</tr>
<tr>
<td><b>Primair domein</b></td>
<td>
<div id="dropdown3" class="dropdown">
<div id="dd3" class="funnelFiltermenu">
<input type="text" name="aansturing" value="<?= getProjectData(2, 6) ?>" class="field" readonly />
<ul id="ul3" class="funnelFilterlist"></ul>
</div>
</div>
</td>
</tr>
<tr>
<td><b>Aansturing door</b></td>
<td>
<div id="dropdown4" class="dropdown">
<div id="dd4" class="funnelFiltermenu">
<input type="text" name="aansturing" value="<?= getProjectData(2, 7) ?>" class="field" readonly />
<ul id="ul4" class="funnelFilterlist"></ul>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
And only add the in javascript:
var gDomains = ["Rapportage", "Relaties", "Leden", "Projecten", "Personeel", "Boekhouding", "Faciliteren", "Verkoop", "Inkoop"];
var gInitiatief = ["SSC", "BIP", "ICCO", "C&F", "IO", "FZ", "KIA", "KIO", "JOP", "MWK", "HRM"];
var gAansturing = ["RegieOverleg", "Beleidstafel", "Lijnmanagement", "Stuurgroep"];
// Add the items of the drop down menu
$.each(gInitiatief, function(index,item) {
$("#ul2").append('<li>'+item+'</li>')
});
// Add the items of the drop down menu
$.each(gDomains, function(index,item) {
$("#ul3").append('<li>'+item+'</li>')
});
// Add the items of the drop down menu
$.each(gAansturing, function(index,item) {
$("#ul4").append('<li>'+item+'</li>')
});
I think that because the IDs are now hard coded, the problem is no longer there.
Related
<div class="form-inline">
<div class="form-group col-lg-4">
<label>Select Item:</label>
<div id="field1">
<select class="form-control" name="item_1">
<?php if($item !=0){foreach ($item as $list_item){?>
<option value="<?php echo $list_item['item'];?>">
<?php echo $list_item[ 'item'];?>
</option>
<?php }}else {?>
<option value="">No Items Available</option>
<?php }?>
</select>
</div>
</div>
<div class="form-group col-lg-2">
<label>Quantity:</label>
<div id="field2">
<input type="number" min="1" class="form-control input-md" name="quantity_1" />
</div>
</div>
<div class="form-group col-lg-3">
<label>Cost(per piece):</label>
<div id="field3">
<input type="number" min="1" class="form-control input-md" name="cost_1" />
</div>
</div>
<div class="form-group col-lg-3" style="margin-top:25px">
<div id="field4">
<button id="addmore" onclick="add();" class="btn add-more" type="button">+</button>
</div>
</div>
</div>
I have these three fields('item, quantity and cost') and these three fields are added incrementally on clicking + button but i am having removing these buttons on - click.
I simply need these three input fields to be added at one click and remove these fields on one click as well. also these fields name should be incremented.
<script>
function add() {
i++;
var div1 = document.createElement('div');
div1.innerHTML = '<select class="form-control" name="item_' + i + '"> <option value=""></option></select>';
document.getElementById('field1').appendChild(div1);
var div2 = document.createElement('div');
div2.innerHTML = '<input type="number" min="1" class="form-control input-md" name="quantity_' + i + '" />';
document.getElementById('field2').appendChild(div2);
var div3 = document.createElement('div');
div3.innerHTML = '<input type="number" min="1" class="form-control input-md" name="cost_' + i + '" />';
document.getElementById('field3').appendChild(div3);
var div4 = document.createElement('div');
div4.innerHTML = '<button id="remove" onclick="remove_btn(this)" class="btn remove" type="button">-</button>';
document.getElementById('field4').appendChild(div4);
}
</script>
There are several issues:
Avoid putting blobs of HTML in your javascript, put your HTML in the HTML file.
Avoid IDs, particularly when they will certainly be duplicated. Duplicate IDs are illegal. Only the first one can be found with a lookup.
Avoid concatenating together strings of text to generate your HTML. It is a too easy to make a mistake and put an XSS vulnerability in your code that way.
(function($) {
"use strict";
var itemTemplate = $('.example-template').detach(),
editArea = $('.edit-area'),
itemNumber = 1;
$(document).on('click', '.edit-area .add', function(event) {
var item = itemTemplate.clone();
item.find('[name]').attr('name', function() {
return $(this).attr('name') + '_' + itemNumber;
});
++itemNumber;
item.appendTo(editArea);
});
$(document).on('click', '.edit-area .rem', function(event) {
editArea.children('.example-template').last().remove();
});
$(document).on('click', '.edit-area .del', function(event) {
var target = $(event.target),
row = target.closest('.example-template');
row.remove();
});
}(jQuery));
.hidden { display: none; }
.formfield { float: left; }
.example-template { clear: left; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hidden">
<div class="example-template">
<div class="formfield"><input placeholder="Name" name="name"></div>
<div class="formfield"><input placeholder="Addr" name="addr"></div>
<div class="formfield"><input placeholder="Post" name="post"></div>
<div class="formfield"><button class="del">-</button></div>
</div>
</div>
<div class="edit-area">
<div class="controls">
<button class="add">+</button>
<button class="rem">-</button>
</div>
</div>
This works by first grabbing the row template out of the hidden div element, and storing it in a variable. Each time it needs to make a new row, it clones the template and updates it. It updates it by adjusting the name element as required, appending "_" and a number. Once it has customized this copy of the template, it appends it to the edit area.
You can remove elements with a reference to the parent using similar syntax with the following:
var childElement = document.getElementById("myChildElement");
document.getElementById("myElement").removeChild(childElement);
Similar to what is described here: http://www.w3schools.com/js/js_htmldom_nodes.asp
Also, consider a toggle on the CSS style property: "display: none;"
I need your help. Trying to build form in php + jquery, and have trouble with some functionality.
For example, I have this code:
<form action="" method="post" id="multiform">
<!-- Product selector -->
<table class="multi" id="MultiRow">
<tr><td>
<select name="store[product][]" required>
<option value="" selected="selected">-Product-</option>
<option value="430">OCTA</option>
<option value="440">KASKO</option>
<option value="19041">TRAVEL</option>
<option value="19063">HOUSEHOLD</option>
</select>
</td>
<!-- /Product selector -->
</table>
<input type="submit" value="ok">
How can I do that, If selected value is 430 or 440, then at right side inserts
<td><input type="text" id="motor[]" name="multiarray[vehicle_type][]"></td>
<td><input type="text" id="deadline[]" name="multiarray[end_date][]"></td>
<td><a class="del" href="#">DELETE BUTTON</a></td>
If selected value is 19041 or 19063, then inserts
<td><input type="text" id="location[]" name="multiarray[travel_location][]"></td>
<td><a class="del" href="#">DELETE BUTTON</a></td>
I need that there also will be +Add button and -delete button where i write:
<a class="del" href="#">DELETE BUTTON</a>
But for datepicker functionality I need that id for inputs will be unique, for ex: id="location1" , at next added row id="location2".
JsFiddle
$("#productselect").change(function(){
var select = document.getElementById("productselect");
var selecedproduct = select.options[select.selectedIndex].value;
$("tr[id^='forselect']").remove();
if(selecedproduct==430 || selecedproduct==440 )
{
var html ='<tr id="forselect"><td><input type="text" id="motor[]" name="multiarray[vehicle_type][]"></td>';
html +='<td><input type="text" id="deadline[]" name="multiarray[end_date][]"></td>';
html +='<td><a class="del" OnClick="removetags();return false;" href="#">DELETE BUTTON</a></td></tr>';
html +='<tr id="forselect"><td>add datepicker </td></tr>';
$("#MultiRow").append(html);
}
else if(selecedproduct==19041 || selecedproduct==19063 )
{
var html ='<tr id="forselect"><td><input type="text" id="location[]" name="multiarray[travel_location][]"></td>';
html +=' <td><a class="del" OnClick="removetags();return false;" href="#">DELETE BUTTON</a></td></tr>';
html +='<tr id="forselect"><td>add datepicker </td></tr>';
$("#MultiRow").append(html);
}
});
deldatepicker = function deldatepicker(id)
{
$("#remove"+id).remove();
}
adddatepicker = function adddatepicker()
{
var N = $("input[id^='location']").length;N++;
var html ='<tr id="remove'+N+'"><td><input type="text"id="location'+N+'" placeholder="date"></td><td><button OnClick="deldatepicker('+N+')">delete datepicker </button> </td></tr>';
$("#MultiRow").append(html);
$("#location"+N).datepicker();
}
removetags = function removetags()
{
$("tr[id^='forselect']").remove();
}
It may help you for you work.
Here it is.
Since you need the ids to be unique I have used Date.now() and then object.now.getUTCMilliseconds(). That will ensure that event when you delete and reinsert another row with same rowIndex it will not crash. Then the rest is trivial!
jQuery(document).ready(function(){
jQuery('select').on('change', function(e){
var tr = jQuery(this).closest('tr').get(0);
var cell = tr.insertCell(1);
var now = Date.now();
switch(jQuery('option:selected', this).val()){
case '430':
case '440':
cell.innerHTML = "<td><input type='text' id='motor[]' name='multiarray[vehicle_type][]'></td><td><input type='text' id='deadline[]' name='multiarray[end_date][]'></td><td><a class='del' href='#'>DELETE BUTTON</a></td><td><a class='del' href='#'>DELETE BUTTON</a></td>";
break;
cell.innerHTMl = "<td><input type='text' id='location"+now.getUTCMilliseconds()+"[]' name='multiarray[travel_location][]'></td><td><a class='del' href='#'>DELETE BUTTON</a></td><td><a class='del' href='#'>DELETE BUTTON</a></td>";
case '19041':
case '19063':
break;
}
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<form action="" method="post" id="multiform">
<!-- Product selector -->
<table class="multi" id="MultiRow">
<tr><td>
<select name="store[product][]" required>
<option value="" selected="selected">-Product-</option>
<option value="430">OCTA</option>
<option value="440">KASKO</option>
<option value="19041">TRAVEL</option>
<option value="19063">HOUSEHOLD</option>
</select>
</td>
<!-- /Product selector -->
</table>
<input type="submit" value="ok">
I am using this code to generate dynamically ADD More input fields and then plan on using Save button to save their values in database. The challenge is that on Save button, I want to keep displaying the User Generated Input fields. However they are being refreshed on Save button clicked.
javascript:
<script type="text/javascript">
var rowNum = 0;
function addRow(frm) {
rowNum++;
var row = '<p id="rowNum' + rowNum + '">Item quantity: <input type="text" name="qty[]" size="4" value="' + frm.add_qty.value + '"> Item name: <input type="text" name="name[]" value="' + frm.add_name.value + '"> <input type="button" value="Remove" onclick="removeRow(' + rowNum + ');"></p>';
jQuery('#itemRows').append(row);
frm.add_qty.value = '';
frm.add_name.value = '';
}
function removeRow(rnum) {
jQuery('#rowNum' + rnum).remove();
}
</script>
HTML:
<form method="post">
<div id="itemRows">Item quantity:
<input type="text" name="add_qty" size="4" />Item name:
<input type="text" name="add_name" />
<input onclick="addRow(this.form);" type="button" value="Add row" />
</div>
<p>
<button id="_save">Save by grabbing html</button>
<br>
</p>
</form>
One approach is to define a template to add it dynamically via jQuery
Template
<script type="text/html" id="form_tpl">
<div class = "control-group" >
<label class = "control-label"for = 'emp_name' > Employer Name </label>
<div class="controls">
<input type="text" name="work_emp_name[<%= element.i %>]" class="work_emp_name"
value="" />
</div>
</div>
Button click event
$("form").on("click", ".add_employer", function (e) {
e.preventDefault();
var tplData = {
i: counter
};
$("#word_exp_area").append(tpl(tplData));
counter += 1;
});
The main thing is to call e.preventDefault(); to prevent the page from reload.
You might want to check this working example
http://jsfiddle.net/hatemalimam/EpM7W/
along with what Hatem Alimam wrote,
have your form call an upate.php file, targeting an iframe of 1px.
I have the following script that sends an image URL to an input field on click (from a modal window). I am also sending that same url, imgurl to a <div class="preview-image> to show it on insertion.
var BusiPress_Configuration = {
init : function() {
this.files();
},
files : function() {
if ( $( '.busipress_upload_image_button' ).length > 0 ) {
window.formfield = '';
$('.busipress_upload_image_button').on('click', function(e) {
e.preventDefault();
window.formfield = $(this).parent().prev();
window.tbframe_interval = setInterval(function() {
jQuery('#TB_iframeContent').contents().find('.savesend .button').val(busipress_vars.use_this_file).end().find('#insert-gallery, .wp-post-thumbnail').hide();
}, 2000);
if (busipress_vars.post_id != null ) {
var post_id = 'post_id=' + busipress_vars.post_id + '&';
}
tb_show(busipress_vars.add_new_file, 'media-upload.php?' + post_id +'TB_iframe=true');
});
window.original_send_to_editor = window.send_to_editor;
window.send_to_editor = function (html) {
if (window.formfield) {
imgurl = $('a', '<div>' + html + '</div>').attr('href');
window.formfield.val(imgurl);
window.clearInterval(window.tbframe_interval);
tb_remove();
$('.preview-image img').attr('src',imgurl);
} else {
window.original_send_to_editor(html);
}
window.formfield = '';
window.imagefield = false;
}
}
}
}
BusiPress_Configuration.init();
Sending the image URL to the editor and the div are working fine, but it is doing it for every instance of that div on the page. I've been playing around with $(this) and closest() to see if I could localize the insertion to the specific div near the input, but haven't had any luck. Any help would be greatly appreciated. Thanks!
Default markup
<table class="form-table">
<tbody>
<tr valign="top">
<th scope="row">Default Map Icon</th>
<td>
<input type="text" class="-text busipress_upload_field" id=
"busipress_settings_map[default_map_icon]" name=
"busipress_settings_map[default_map_icon]" value=
"http://localhost/jhtwp/wp-content/plugins/busipress/img/red-dot.png" /><span> <input type="button"
class="busipress_upload_image_button button-secondary" value=
"Upload File" /></span> <label for=
"busipress_settings_map[default_map_icon]">Choose the default map icon (if
individual business type icon is not set</label>
<div class="preview-image" style="padding-top:10px;"><img src=
"http://localhost/jhtwp/wp-content/plugins/busipress/img/red-dot.png" /></div>
</td>
</tr>
<tr valign="top">
<th scope="row">Active Map Icon</th>
<td>
<input type="text" class="-text busipress_upload_field" id=
"busipress_settings_map[active_map_icon]" name=
"busipress_settings_map[active_map_icon]" value=
"http://localhost/jhtwp/wp-content/plugins/busipress/img/blue-dot.png" /><span> <input type="button"
class="busipress_upload_image_button button-secondary" value=
"Upload File" /></span> <label for=
"busipress_settings_map[active_map_icon]">Choose the active map icon (if
individual business type icon is not set</label>
<div class="preview-image" style="padding-top:10px;"><img src=
"http://localhost/jhtwp/wp-content/plugins/busipress/img/blue-dot.png" /></div>
</td>
</tr>
</tbody>
</table>
Assuming you can select the button already (I changed it to "button-selector" for the meantime), use parent to get the parent td then find the child div to be changed. This will get the nearest div to your button.
$("button-selector").parent('td').find("div")
I have a dropdownlist with values. On a click of a button a unordered list gets appended with an <li> with details from the selected item in the dropdown list.
The <li> has an <a> tag in it which will remove the <li> from the <ul>.
I need to repopulate the dropdown list with the item removed from the <ul> when the <li> is removed.
Any ideas?
UPDATE:
Thanks for all your help. Here is my whole implementation:
<script type="text/javascript">
$(function() {
$("#sortable").sortable({
placeholder: 'ui-state-highlight'
});
$("#sortable").disableSelection();
$('#btnAdd').click(function() {
if (validate()) {
//Remove no data <li> tag if it exists!
$("#nodata").remove();
$("#sortable").append("<li class='ui-state-default' id='" + $("#ContentList option:selected").val() + "-" + $("#Title").val() + "'>" + $("#ContentList option:selected").text() + "<a href='#' title='Delete' class='itemDelete'>x</a></li>");
$("#ContentList option:selected").hide();
$('#ContentList').attr('selectedIndex', 0);
$("#Title").val("");
}
});
$('#btnSave').click(function() {
$('#dataarray').val($('#sortable').sortable('toArray'));
});
$('.itemDelete').live("click", function() {
var id = $(this).parent().get(0).id;
$(this).parent().remove();
var value = id.toString().substring(0, id.toString().indexOf('-', 0));
if ($("option[value='" + value + "']").length > 0) {
$("option[value='" + value + "']").show();
}
else {
var lowered = value.toString().toLowerCase().replace("_", " ");
lowered = ToTitleCase(lowered);
$("#ContentList").append("<option value='" + value + "'>" + lowered + "</option>");
}
});
});
function validate() {
...
}
function ToTitleCase(input)
{
var A = input.split(' '), B = [];
for (var i = 0; A[i] !== undefined; i++) {
B[B.length] = A[i].substr(0, 1).toUpperCase() + A[i].substr(1);
}
return B.join(' ');
}
</script>
<form ...>
<div class="divContent">
<div class="required">
<label for="ContentList">Available Sections:</label>
<select id="ContentList" name="ContentList">
<option value="">Please Select</option>
<option value="CHAN TEST">Chan Test</option>
<option value="TEST_TOP">Test Top</option>
</select>
<span id="val_ContentList" style="display: none;">*</span>
</div>
<div class="required">
<label for="ID">Title:</label>
<input class="inputText" id="Title" maxlength="100" name="Title" value="" type="text">
<span id="val_Title" style="display: none;">*</span>
</div>
<input value="Add Section" id="btnAdd" class="button" type="button">
</div>
<ul id="sortable">
<li class="ui-state-default" id="nodata">No WebPage Contents Currently Saved!</li>
</ul>
<div>
<input type="submit" value="Save" id="btnSave" class="button"/>
</div>
<input type="hidden" id="dataarray" name="dArray" />
</form>
You've acknowledged that you know very little about jQuery, so let's look at some of this piece by piece. This snippets will give you the information you need to construct your solution.
Adding click-events is relatively easy:
$("#myButton").click(function(){
/* code here */
});
Removing elements is also pretty simple:
$("#badThing").remove();
The thing about .remove() though is that you can add it elsewhere after removing it:
$("#badThing").remove().appendTo("#someBox");
That moves #badThing from wherever it was, to the inside of #someBox.
You can add new list items with the append method:
$("#myList").append("<li>My New Item</li>");
You can get the selected item of a drop-down like this:
var item = $("#myDropDown option:selected");