I have a jsfiddle here which you can use to see a basic demo of my application and the problem I am having.
When you open fiddle please follow these steps below:
You will see an "Open Grid" link, click on the link and select either "True or False" or "Yes or No" buttons.
After selecting either of the buttons you will see their answer buttons appear underneath.
Please click on the "Add Question" button and this will appended a table row into the table underneath.
Now in the appended row is the problem. If you click on the "Open Grid" link within the appended row and select either of the buttons, you will realise that the corresponding answer buttons underneath disappears. They should be displayed not disappear.
So my question is that can anyone modify the demo so that they can get the corresponding answer buttons to appear within the appended row when the user clicks on the "Open Grid" link in the appended row?
I think the problem maybe within this code but I am not sure:
var count = 0;
var plusbutton_clicked;
var gQuestionIndex = 0;
function insertQuestion(form) {
var context = $('#optionAndAnswer');
var currenttotal = context.find('.answerBtnsOn').length;
var $tbody = $('#qandatbl > tbody');
var $tr = $("<tr class='optionAndAnswer' align='center'>");
var $td = $("<td class='extratd'>");
var $options = $("<div class='option'>1. Option Type:<br/></div>");
var $answer = $("<div class='answer'>3. Answer:<br/></div>");
gQuestionIndex++;
$('.gridTxt', context).each(function() {
var $this = $(this);
var $optionsText = $("<input type='text' class='gridTxtRow maxRow' readonly='readonly' />").attr('name', $this.attr('name') + "[]").attr('value', $this.val()).appendTo($options).after("<span href='#' class='showGrid'>[Open Grid]</span>");
$questionType = $this.val();
});
var $this, i = 0,
$row, $cell;
$('#optionAndAnswer .answers').each(function() {
$this = $(this);
if (i % 7 == 0) {
$row = $("<tr/>").appendTo($answer);
$cell = $("<td/>").appendTo($row);
}
var $newBtn = $(("<input class='answerBtnsRow answers' type='button' style='display:%s;' onclick='btnclick(this, " + gQuestionIndex + ");' />").replace('%s', $this.is(':visible') ? 'inline-block' : 'none')).attr('name', "value[" + gQuestionIndex + "][]").attr('value', $this.val()).attr('class', $this.attr('class')).attr('id', $this.attr('id') + 'Row');
$newBtn.appendTo($cell);
i++;
});
$tr.append($td);
$td.append($options);
$td.append($answer);
$tbody.append($tr);
count++;
$('#optionAndAnswer .answerBtns').hide();
$('#optionAndAnswer .answerBtns').removeClass('answerBtnsOn').addClass('answerBtnsOff');
updateAnswer($answer, gQuestionIndex);
}
Thanks
I think the main problems may be in insertQuestion().
As far as I can tell :
$cell is defined conditionally but the line $newBtn.appendTo($cell); is unconditional. When the condition is not met, the append statement will fail silently (no error message).
even on the occasions that the condition is met $newBtn is successfully appended to $cell, and $cell is appended to $row, but $row is never appended to anything. Consequently no newBtns will appear in the DOM.
Edit:
Try replacing :
if (clickedNumber === 'True or False') {
$(this).closest('.option').siblings('.answer').find('input[name="answerName[True]"]').show();
$(this).closest('.option').siblings('.answer').find('input[name="answerName[False]"]').show();
} else if (clickedNumber === 'Yes or No') {
$(this).closest('.option').siblings('.answer').find('input[name="answerName[Yes]"]').show();
$(this).closest('.option').siblings('.answer').find('input[name="answerName[No]"]').show();
}
with :
var ans = $(this).closest('.option').siblings('.answer').find('input');
if (clickedNumber === 'True or False') {
ans.filter('[value="True"], [value="False"]').show();
} else if (clickedNumber === 'Yes or No') {
ans.filter('[value="Yes"], [value="No"]').show();
}
Related
I have a view with a table with single selection mode and a button in its toolbar to delete selected row.
Though when I press the button, it deletes all the rows instead.
My code:
View file:
<template data-controller-name="myapplication.myview2">
<div data-sap-ui-type="sap.ui.table.Table" id="tb1" data-width="100%" data-title="Person Table"></div>
</template>
Controller File:
onInit: function() {
try {
var oTab = [
// the table content
];
var oToolbar = new sap.ui.commons.Toolbar();
oToolbar.addItem(new sap.ui.commons.Button({text: "Delete selected row",
press: function() {
try {
var newTab = this.getParent().getParent();
var index = newTab.getSelectedIndex();
if (index == -1)
alert("No row selected");
else {
var currModel = newTab.getModel();
var selectedRow = newTab.getRows()[index];
newTab.removeRow(selectedRow);
currModel.setData({table: newTab});
newTab.bindRows("/table");
}
} catch (err) {
txt = "There was an error on this page.\n\n";
txt += "Error description: " + err.message + "\n\n";
txt += "Click OK to continue.\n\n";
alert(txt);
}
}}));
this.byId("tb1").setToolbar(oToolbar);
this.byId("tb1").setVisibleRowCount(5);
this.byId("tb1").setNavigationMode(sap.ui.table.NavigationMode.Paginator);
// Columns definition should be HERE
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({table: oTab});
this.byId("tb1").setModel(oModel);
this.byId("tb1").bindRows("/table");
} catch (err) {
txt = "There was an error on this page.\n\n";
txt += "Error description: " + err.message + "\n\n";
txt += "Click OK to continue.\n\n";
alert(txt);
}
},
// More functions....
Any ideas please?
You need to remove row from model, not from table directly.
Here is an example on how to do this.
http://jsbin.com/yewula/1/edit
Like many folks have suggested, we should removed it from the model. Since table is binded to the model, table will refresh accordingly.
-D
In your press function for the delete button, get more details about the table:
var tableIndex = newTab.getSelectedIndex();
var context = newTab.getContextByIndex(tableIndex);
var path = context.getPath();
In the variable path you will then find the data index that corresponds to the table row index. Use this data index to remove the row from the model.
currModel.oData.table.splice(data_index, 1);
Afterwards, all that should be needed is a refresh of the model to inform the controls about the changed data. And, for the user it might also be nice if the selection in the table gets reset as well.
currModel.refresh();
newTab.setSelectedIndex(-1);
In my adventure to create a To-Do list application, I've run into another problem. In my code, every time a user clicks New Category a new div will appear with their custom name and number of forms.
However, when another div is created, its' forms are given to the previous div. Here's that code:
<script src="http://code.jquery.com/jquery-2.0.0.js"></script>
<script type='text/javascript' src="script.js"></script>
<script>
$(function() {
$("#new").click(function() {
var canContinue = true;
var newCategory = prompt("Enter the name you want for your category:");
if(newCategory.length === 0){
confirm("A new category can not be created - nothing was entered in the text area.");
canContinue = false;
}
if(canContinue){
var categorySections = prompt("Enter the number of sections needed for this category:");
$("body").append("<div id = \"newDiv\"><p>" + newCategory + "</p></div>");
}
for(var i = 0; i < categorySections; i++){
$("#newDiv").append("<form> Thing to do: <input type = \"text\"></form><br>");
}
});
});
</script>
So, I tried creating a separate function using the this keyword where the forms were created after the div was ready, but now no forms are created at all!
Here's that code:
$(function(){
$("#newDiv").ready(function() {
for(var i = 0; i < categorySections; i++){
$(this).append("<form> Thing to do: <input type = \"text\"></form><br>");
}
});
});
So, how do I create forms for each separate div?
You're repeatedly creating divs with the same ID. (a) that's not legal and (b) if you do it anyway, your $(#newDiv) selector will always apply to the first one.
Also, you're appending to #newDiv outside the if (canContinue) check.
Try:
if(canContinue){
var categorySections = prompt("Enter the number of sections needed for this category:");
var newDiv = $("<div>").appendTo($(document.body));
var header = $('<p>').text(newCategory).appendTo(newDiv);
for(var i = 0; i < categorySections; i++){
newDiv.append("<form> Thing to do: <input type = \"text\"></form><br>");
}
}
jsFiddle
You can't use the ID newDiv multiple times, HTML IDs must be unique. Additionally, your flow can be cleaned up a bit, as below.
$(function () {
$("#new").click(function () {
var newCategory = prompt("Enter the name you want for your category:");
if (newCategory.length === 0) {
confirm("A new category can not be created - nothing was entered in the text area.");
return false;
}
var categorySections = prompt("Enter the number of sections needed for this category:");
var $div = $("<div />", {
html: "<p>" + newCategory + "</p>"
});
$("body").append($div);
for (var i = 0; i < categorySections; i++) {
$div.append("<form> Thing to do: <input type='text'/></form><br>");
}
});
});
I have a delete function within a function where if the user clicks on the "Delete" button, it displays a message stating that a file has been deleted. The code which does this is below:
$("#imagemsg").html(data);
But the problem is that let's say that I have 4 table rows and I delete a file in the 3rd row, the message should be displayed in the 3rd row only but instead it is displayed in the first row. Another example is that let's say that I have 8 table rows and I delete a file in the 6th row, the message should be displayed in the 6th row only but instead it is displayed in the first row.
Why is the message that is suppose to appear after a file is deleted is always displayed in the first row and not within the row the file has been deleted from?
Below is full code:
var counter = 0;
counter++;
function stopImageUpload(success, imagefilename){
var result = '';
if (success == 1){
result = '<span id="imagemsg'+counter+'">The file was uploaded successfully!</span><br/><br/>';
$('.listImage').eq(window.lastUploadImageIndex).append('<div>' + htmlEncode(imagefilename) + '<button type="button" class="deletefileimage" image_file_name="' + imagefilename + '">Remove</button><br/><hr/></div>');
}
else {
result = '<span id="imageemsg">There was an error during file upload!</span><br/><br/>';
}
$(".deletefileimage").on("click", function(event) {
var image_file_name = $(this).attr('image_file_name');
jQuery.ajax("deleteimage.php?imagefilename=" + image_file_name)
.done(function(data) {
$("#imagemsg" + counter).html(data);
});
$(this).parent().remove();
});
return true;
}
Below is the deleteimage.php script where the delete message is retrieved from:
<?php
$image_file_name = $_GET["imagefilename"];
echo "$image_file_name was Deleted";
unlink("ImagesFilesFolder/$image_file_name");
?>
The problem seems to be this:
.done(function(data) {
$("#imagemsg" + counter).html(data);
You set counter like this
var counter = 0;
counter++;
But you never seem to refer to the variable again. In any case, this variable is global - the command above will always target the ID with the current number of the counter, so it will not target the tr corresponding to the clicked button.
Since you use
$(this).parent().remove();
I assume that the parent is the tr concerned? In this case you could use a class instead of an ID 'imagemsg' and then do
$(this).parent().find(".imagemsg").html(data);
This would target the message inside the same row of the button.
I have a report populated as a table with a stringbuilder from the codebehind. The first TD of every row is a checkbox, the id of each checkbox is assigned dynamically:
sb.Append("<td><input type='checkbox' id='chkSelectAll_" + i + "' name='chk_" + i + "' onclick='JavaScript: chkAll_click(this);' /> </td>"
The aspx page uses a master page and
<asp:Content><div id='divMain'></div></asp:Content>
format other than a form to populate. The problem I am running in to is that I am having trouble finding all the elements (or any actually) of the div to work with. Here is the javascript I have been given. (Team project at work, I was just assigned 1 task on the project so changing anything is not an option.)
function divBatchBuild_click() {
debugger
var form = document.forms[0];
var visitList = '';
for (i = 0; i < form.elements.length; i++) {
if (form.elements[i].type == 'checkbox') {
//alert(form.elements[i].id.toString());
if (form.elements[i].checked == true &&
form.elements[i].id != 'chkSelectAll') {
var y = form.elements[i].id;
//alert('id=' + y[1].toString());
visitList = visitList + y[i].toString() + '|';
}
}
}
}
Apparently this worked on a previous project, but when used with this report the process never goes inside the if statement. Any help on what is going wrong is appreciated.
I think you want to first get the div, then get the elements in the div with the checkbox tagname. Something like:
var div = document.getElementById('divMain');
var elements = div.getElementsByTagName('checkbox');
for (i = 0; i < elements.length; i++) {
General Info:
Aspx page holds an Ascx User control. Inside the User control, the Repeater is contained inside a View, contained inside a Multiview.
Asp.Net 2.0 framework / C#
Details:
I have a repeater (inside an ascx user control) that shows records, and the first column is a checkbox. If checked, that row will be deleted.
OUtside the repeater, I have a button that will deleted all rows that are checked.
Everything works fine, but have been asked to add a pop up "confirm delete" message that includes the number of records that will be deleted if the user clicks "Ok" on the pop up.
Something like:
"You are about to delete 8 records".
Currently my button looks like this:
<asp:Button ID="btnDeleteAllRecords" runat="server" Text="Delete all Checked Records" Onclick="btnDeleteAllRecords_Click" OnClientClick="javascript:GetCbCount();" />
I have this javascript code block:
<script type="text/javascript">
function GetCbCount()
{
var cb = document.getElementById("rptrVoicemail").getElementsByTageName("input");
var cbCount;
for(i = 0; i < cb.lenght; i++)
{
if(cb[i].type == "checkbox")
{
if(cb[i].checked)
{
cbCount = cbCount + 1;
}
}
}
return confirm('You are about to delete' + cbCount + 'records.');
}
</script>
When I click my button I'm getting:
Error: 'document.getElementById(...)' is null or not an object
on this line:
var cb = document.getElementById("rptrVoicemail").getElementsByTageName("input");
Why is the JS not seeing my repeater? Is it because it's buried inside a MultiView? How can the JS be corrected so that the pop up will show the record count in the message?
UPDATE:
I changed the script to:
function GetCbCount(){
var inpt = document.getElementById("vmDiv");
var checkboxes = inpt.getElementsByTagName("input");
var cbCount;
for(i = 0; i<checkboxes.lenght;i++){
if (checkboxes[i].type == "checkbox" && checkboxes[i].checked){
cbCount = cbCount + 1;
}
}
return confirm('You are about to delete ' + cbCount + ' Voicemails.');
}
This should work:
document.getElementById('<%= rptrVoicemail.ClientID %>').getElementsByTageName("input");
Another approach is this little script that returns the ClientID. You could add it even to an included JS-file.
function GetClientId(strid)
{
var count=document.forms[ 0 ].length ;
var i = 0 ;
var eleName;
for (i = 0 ; i < count ; i++ )
{
eleName = document.forms [ 0 ].elements[ i ].id;
pos=eleName.indexOf( strid ) ;
if(pos >= 0) break;
}
return eleName;
}
Found here.
If you are using a master page or nesting controls (inside ascx, view, etc.) the framework will change the IDs that are rendered with elements.
If you do a "View Source" or use FireBug, you might see that rptrVoicemail became something like ctl00_ContentPlaceHolder1_someUserControl_ctl00_multiViewID_ctl28_rptrVoicemail.
You can use getElementById('<%= rptrVoicemail.ClientID %>') to get at the ID of the element as it would be rendered on the client.
Edit: To help debug, do something like this... you get the point.
var rptr = document.getElementById('<%= rptrVoicemail.ClientID %>');
rptr.borderColor = 'pink'; // draw a border to check it's the right element