I'm making a table.
I've made my rows editable with: ng-click="todo.editing = !todo.editing"
index.html
<tr ng-repeat="todo in todos>
<td>
<div ng-hide="todo.editing">{{ todo.id }} </div>
<div ng-show="todo.editing"><input type="id" ng-model="todo.id" /></div>
</td>
<td>
<div ng-hide="todo.editing">{{ todo.text }}</div>
<div ng-show="todo.editing"><input type="text" ng-model="todo.text" /></div>
</td>
</tr>
<button class="btn btn-warning btn-sm ng-scope" ng-click="todo.editing = !todo.editing"><span class="glyphicon glyphicon-pencil"></span></button>
I've made a button to add new rows to the table:
index.html
<button type="button" class="btn btn-default btn-block " ng-click="addRow($storage.todos)">New record</button>
script.js
$scope.addRow = function (arr) {
console.log(arr);
arr.push({'id':$scope.id, 'text': $scope.text});
};
Now I want to expand my addRow() function so I can add a new row and at the same time position myself at that row, and also put me in edit mode.
The problem with position is that I am using pagination. Let's say I am at page one in pagination and the newly row comes at page four. I want to automatically get there.
Can somebody give me a hint? Thanks for your time.
Just make editing property value true during pushing.
Like this
arr.push({'id':$scope.id, 'text': $scope.text,editing:true});
I created a fiddle:
https://jsfiddle.net/0t1trq6m/
addRow() method now looks like:
$scope.addRow = function () {
console.log("test");
var e = new Entry();
e.id = $scope.todos.length;
e.text = $scope.content;
$scope.todos.push(e);
}
Related
i have a view in which i want to show textbox and button to save and edit the database table if in the table id comment is null i want to show textbox to enter the comment and if comment is there in the table then show the comment, but when user clicks the second(edit) button i want that textbox and button should reappear in that place, i put an if condition to check if my table column is null then show textbox and button to enter data into that column and i have second button to get back the textbox and buttons with the comment text.
My code is here
#if (item.Comments == null)
{
<div class="form-inline comments">
<textarea class="form-control commentText" placeholder="Enter Your Comment"></textarea>
<button type="submit" data-cid="#item.RoomId" class="btn btn-primary save"><i class="fas fa-save h3"></i></button>
<button type="submit" data-eid="#item.RoomId" class="btn btn-secondary edit"><i class="fas fa-edit h3"></i></button>
</div>
}
else
{
<div class="commentText">
#Html.DisplayFor(modelItem => item.Comments)
</div>
}
$('.save').click(function () {
var cmt = $('.commentText').val();
$.post("#Url.Action("AddComment", "ReceptionHk")", { id: $(this).data("id"), newComment: cmt });
});
$('.edit').click(function () {
$('.comments').show();
$('.commentText').hide();
});
My Controller Method
public void AddComment(int id, string newComment)
{
var roomcmt = db.SingleOrDefault<Room>(id);
if (ModelState.IsValid)
{
roomcmt.Comments = newComment;
var r = db.Update(roomcmt);
}
}
How to show the textbox and two button again when edit button is clicked
Please help me with this
Change your code in the following way:
A: Remove the line #if (item.Comments == null) and make the view display the creation section by default.
B: For creating/editing the comments have your code something like this:
<div class="form-inline comments">
<textarea class="form-control commentText" placeholder="Enter Your Comment"></textarea>
<button type="submit" data-cid="#item.RoomId" class="btn btn-primary save"><i class="fas fa-save h3"></i></button>
</div>
C: And then add a scope validation on the list as:
#if(item.Comments!=null)
{
<display your list here>
}
For displaying the comments, instead of statically displaying the comments use a table and do a foreach loop on the comments in the table to create rows with 2 columns in it as Comment,Edit.
Ex:
<table>
#foreach(var comment in item.Comments)
{
<tr>
<td>#comment.Text</td>
<td><button data-id="#comment.RoomId">Edit</button></td>
</tr>
}
</table>
and on the click of the Edit button call a javascript function that will call the retrieval of that comment and populate your editing fields after which you can later use it to update.
Your view will look something like this:
<div class="form-inline comments">
<textarea class="form-control commentText" placeholder="Enter Your Comment"></textarea>
<button type="submit" data-cid="#item.RoomId" class="btn btn-primary save"><i class="fas fa-save h3"></i></button>
</div>
#if(item.Comments!=null)
{
<table>
#foreach(var comment in item.Comments)
{
<tr>
<td>#comment.Text</td>
<td><button data-id="#comment.RoomId">Edit</button></td>
</tr>
}
</table>
}
Rest: implement your JS function to retrieve and create the comments.
Would like to ask what is wrong with the functions bellow, the first iteration works without any problem but, after the grid is refreshed, when protractor tries to move to the next cell, it gives me this error message:
Failed: stale element reference: element is not attached to the page document
The idea of this is to read the 5th column (or 4th if you consider stating from 0), check each row that contains the value "true", if contains true then do the operation of editing the row, clicking in a checkbox and saving (everything is performed at the line)
Each element has a unique ID related to status code so that why I am "not using rows" in the function (only to get the text from the line and then pass as string to complete the ID of the element)
**Every time that the value is changed and saved, the table gets a refresh
function resetGoodItemStatus(siteToResetValues){
var cellsConform = element.all(by.css('#datatableDir tr td:nth-of-type(5)'));
var conformCounter = 0;
selectValueDropDown(siteToResetValues)
cellsConform.each((eachCell) => {
eachCell.getText().then((cellText) => {
switch (cellText)
{
case 'true':
element(by.id(conformCounter+'-1')).getText().then(function(value){
element(by.id('btnEdit-US.'+value)).click();
element(by.xpath("//*[#editable-checkbox=\"scopeValue.getConformMapping(scopeValue.getDataRow("+'\'US.'+value+"\')).conform\"]/../span/span/input")).click();
element(by.id('btnSubmit-US.'+value)).click();
})
default:
browser.sleep(100)
}
conformCounter += 1
});
});
}
HTML before editing the line:
<tr role="row" class="odd">
<td id="0-0" class="ng-scope">
<form editable-form="" name="scopeValue.rowforms['US.DAM']" onaftersave="scopeValue.saveData('US.DAM',0)" ng-show="scopeValue.rowforms['US.DAM'].$visible" class="form-buttons form-inline ng-pristine ng-valid ng-hide" style="">
<button type="button" class="btn btn-xs btn-trans kni kni-check-circle text-info" id="btnSubmit-US.DAM" ng-disabled="scopeValue.rowforms['US.DAM'].$waiting" ng-click="scopeValue.rowforms['US.DAM'].$submit()">
</button>
<button type="button" class="btn btn-link kni kni-x-circle-slim" ng-disabled="scopeValue.rowforms['US.DAM'].$waiting" id="btnCancel-US.DAM" ng-click="scopeValue.cancelData('US.DAM',0)">
</button>
</form>
<div class="buttons" ng-show="!scopeValue.rowforms['US.DAM'].$visible">
<button type="button" class="btn btn-xs btn-trans kni kni-edit-circle text-info" ng-click="scopeValue.rowforms['US.DAM'].$show()" id="btnEdit-US.DAM">
</button>
</div></td>
<td id="0-1" class="ng-scope sorting_1">DAM</td>
<td id="0-2" class="ng-scope">US.DAM</td>
<td id="0-3" class="ng-scope">Generic Damaged Code</td>
<td id="0-4" class="ng-scope">
<span editable-checkbox="scopeValue.getConformMapping(scopeValue.getDataRow('US.DAM')).conform" e-name="conform" e-form="scopeValue.rowforms['US.DAM']" e-required="" class="ng-scope ng-binding editable">false</span>
</td></tr>
HTML after clicking at the Edit button:
<td id="0-4" class="ng-scope">
<span editable-checkbox="scopeValue.getConformMapping(scopeValue.getDataRow('US.DAM')).conform" e-name="conform" e-form="scopeValue.rowforms['US.DAM']" e-required="" class="ng-scope ng-binding editable editable-hide">false</span>
<span class="editable-wrap editable-checkbox ng-scope">
<span class="editable-controls"><input type="checkbox" name="conform" required="required" class="editable-input ng-pristine ng-empty ng-invalid ng-invalid-required ng-touched" ng-model="$data" style="">
<div class="editable-error ng-binding ng-hide" ng-show="$error" ng-bind="$error" style=""></div>
</span>
</span>
</td>
Thank you for your time!
One simple way is to get text of all cells in the 5th column into text array, then iterate the text array, the array index is equivalent to the table row index.
Once cell text is equal true, use row index to find the table row. The rest elements can be found within the table row.
Because in each iteration, below code will find all table rows from page again, should not happen Stale Exception
function resetGoodItemStatus(siteToResetValues){
var cellsConform = element.all(by.css('#datatableDir tr td:nth-of-type(5)'));
selectValueDropDown(siteToResetValues);
cellsConform.getText().then(function(conforms) {
// conforms is a string Array, each one is the text of one cell of 5th column
conforms.forEach(function(conform, rowIndex) {
if(conform === 'true') {
var row = element.all(by.css('#datatableDir tr').get(rowIndex);
row.element(by.css('button[id^="btnEdit-US"]')).click();
row.element(by.css('input[type="checkbox"]')).click();
row.element(by.css('button[id^="btnSubmit-US"]')).click();
browser.sleep(3000)
}
});
});
}
I'm rendering the contents of an array using ng-repeat like this-
<tr ng-repeat="option in eventCtrl.questionDetail.options track by $index">
<th scope="row">Option {{$index + 1}}</th>
<td>
<input type="text" ng-model="option" ng-change="eventCtrl.newlyAddedOptions[$index] = option" style="width:100%;">
</td>
<td>
<button type="button" ng-confirm-click="Are you sure to delete?" confirmed-click="eventCtrl.removeOption($index)" class="btn btn-light btn-sm">Delete</button>
</td>
</tr>
<button type="button" class="btn btn-dark" ng-click="eventCtrl.addOption()" id="addNewOption">+ Add New Answer Option</button>
On click of the button I'm insering an empty string into the questionDetail.options array so that I get an empty input field to insert my data.Controller functions looks like this-
myApp.controller('eventController',function(){
let dash=this;
dash.newOption ='';
//store all newoptions to this array before finally updating the
//question
dash.newlyAddedOptions = [];
dash.addOption = () =>{
dash.questionDetail.options.push(dash.newOption);
});
//add new options
dash.updateTheQuestion = () =>{
//add the newly added options in the questionDetail if any which will be finally updated
apiService.updatequestion(dash.params.qid,dash.questionDetail).then(function successCallBack(response) {
$rootScope.$broadcast("loader_hide");
alert(response.data.message);
});
}
Now when I insert data into the field and try to add another option the previously inserted field becomes blank beacuse the questionDetail.options array get rerendered again.However I've used ng-change to collect data and store it into the newlyAddedOptions array.
How do I change the empty strings pushed into array with the value that is retrieved with ng-model="option" so that I could directly push those into questionDetal.options array.
I know this good be done easily and I'm missing something.
Thank You in advance.
Edit:I was pushing an empty string because I wanted a blank input on clicking the add option where I can insert new option.This is mainly the edit question view where user can add an option or delete an option with the options that are coming from the database.
Plunkr-https://plnkr.co/edit/SLfy8qaz8LoHurwpVmw6?p=catalogue
Try this :
<tr ng-repeat="opt in eventCtrl.questionDetail.options track by $index">
<th scope="row">Option {{$index + 1}}</th>
<td>
<input type="text" ng-model="newlyAddedOptions[$index]" style="width:100%;">
</td>
<td>
<button type="button" ng-confirm-click="Are you sure to delete?" confirmed-click="eventCtrl.removeOption($index)" class="btn btn-light btn-sm">Delete</button>
</td>
</tr>
<button type="button" class="btn btn-dark" ng-click="eventCtrl.addOption()" id="addNewOption">+ Add New Answer Option</button>
https://codepen.io/supravi96/pen/bMmpOQ?editors=1010
When the file input changes and receives a value, i want to set that value to a tr.file_name. After that i want to clone that TR and paste it to the
Cloning works, but for multiple files it is not working. Anyone that can help me?
<tr class="file_row">
<td class="file_title"></td>
<td class="text-center">
<a class='btn btn-info btn-xs' href="#">
<span class="glyphicon glyphicon-edit"></span> Edit
</a>
<a href="#" class="btn btn-danger btn-xs">
<span class="glyphicon glyphicon-remove"></span> Del
</a>
</td>
<td>
<div class="fileUpload btn btn-primary btn-xs">
<span><b>+</b> Upload</span>
<input type="file" class="upload" />
</div>
</td>
</tr>
Javascript:
$(document).ready(function(){
var filename
$('.file_row').change(function(){
file();
});
file();
function file(){
var empty = true;
var filename;
$('.file_row').each(function(){
filename = $(this).find('.upload').val();
$(this).find('.file_title').text(filename);
if(filename != ''){
empty = false;
}
});
if(empty == false){
var row = $('.file_row:first-child').clone();
$(row).find('.upload').val('');
$(row).appendTo('table');
}
}
});
I've also made a fiddle.
Change your event binding from this:
$('.file_row').change(function(){
file();
});
To this:
$('table').on('change','.file_row', function(){
file();
});
As the method change only bind to events that are already on the page when you invoke it. Delegating the event to a common parent works when the element is added dynamically.
You forget to clean the file_title in the cloned tr
$(row).find('.file_title').text('');
updated jsfiddle: http://jsfiddle.net/a23ez9eg/4/
i am using bootstrap btngroup to select one value ..how can i display that selected value ?? here is my code.
<div class="input-group">
<div id="radioBtn" class="btn-group">
<a class="btn btn-primary btn-sm active" data-toggle="fun" data- title="Y">YES</a>
<a class="btn btn-primary btn-sm notActive" data-toggle="fun" data-title="X">I don't know</a>
<a class="btn btn-primary btn-sm notActive" data-toggle="fun" data-title="N">NO</a>
</div>
<input type="hidden" name="fun" id="fun">
</div>
and JS
$('#radioBtn a').on('click', function(){
var sel = $(this).data('title');
var tog = $(this).data('toggle');
$('#'+tog).prop('value', sel);
$('a[data-toggle="'+tog+'"]').not('[data- title="'+sel+'"]').removeClass('active').addClass('notActive');
$('a[data-toggle="'+tog+'"][data-title="'+sel+'"]').removeClass('notActive').addClass('active');
})
Tidy your code - remove the spaces in your data- title attribute, in both the HTML and JS, as these are causing it to break.
Add a <div id="display"></div> in your HTML somewhere and style it how you like.
Add this line to your JS click handler: $('#display').html(sel);
Here's a demo.
If you'd prefer the result to be the text of the radio button instead of the value, use $('#display').html($(this).html()); instead in step 3.
Done.
Not sure if this is what you mean, but to get the value (or text) from a clicked button in a button group, I use for example.....
HTML
<div id="aBtnGroup" class="btn-group">
<button type="button" value="L" class="btn btn-default">Left</button>
<button type="button" value="M" class="btn btn-default">Middle</button>
<button type="button" value="R" class="btn btn-default">Right</button>
</div>
<p>
<div>Selected Val: <span id="selectedVal"></span></div>
JS
$(document).ready(function() {
// Get click event, assign button to var, and get values from that var
$('#aBtnGroup button').on('click', function() {
var thisBtn = $(this);
thisBtn.addClass('active').siblings().removeClass('active');
var btnText = thisBtn.text();
var btnValue = thisBtn.val();
console.log(btnText + ' - ' + btnValue);
$('#selectedVal').text(btnValue);
});
// You can use this to set default value upon document load
// It will fire above click event which will do the updates for you
$('#aBtnGroup button[value="M"]').click();
});
CONSOLE OUTPUT
Left - L
Middle - M
Right - R
Hope this helps
Plunker here