Unable to make the contentEditable dynamicallly for inline editing in angular2+ - javascript

here i am a issue
below is my json data:
info = [{
'id':1,'name': 'mr.x',
},{
'id':2,'name': 'mr.y',
},{
'id':3,'name': 'mr.z',
},{
'id':4,'name': 'mr.a',
}]
i am displaying this in the template
<div *ngFor="let x of info;let i = index">
<div id="{{x.id}}">
<div id="{{x.id}}">
</div>
<span [contentEditable]="content" id="{{x.id}}" > {{x.name}}</span>
<button id="edit" (click)="edit(x.id)">edit
</button>
here what i am trying is for each span element the {{x.name}} is display i want to change that name and so what i did was
edit(id){
this.content = true;
}
it is not working nothing editable
now my issues are how can i make it editable based on click event and how can i get the value of the span and display the change as the change has to go to the server and display
my stack link
https://stackblitz.com/edit/angular-gdqxwx

Trick here is you need to create a dynamic property based on index i.e PropertyName[i].
Code:
hideElement = {}; // declare in .ts file
Html:
<div *ngFor="let x of info;let i = index">
<div id="{{x.id}}">
<div id="{{x.id}}">
</div>
<span [hidden]="!!hideElement[i]" id="{{x.id}}"> {{x.name}}</span>
<input [(ngModel)]='x.name' type="text" [hidden]="!hideElement[i]" />
<button id="edit" [hidden]='hideElement[i]' (click)="hideElement[i]=true">edit </button>
<button id="save" [hidden]='!hideElement[i]' (click)="hideElement[i]=false">save </button>
</div>
working sample here

Related

Javascript - Retrieving values of a div when a button inside that div is clicked

I'm writing the code to edit a database table.
I have the following HTML:
<div id="1">
<div contenteditable>aaa</div>
<div contenteditable>bbb</div>
<div contenteditable>ccc</div>
<button onClick="a('save')">SAVE</button>
<button onClick="a('delete')">DELETE</button>
</div>
<div id="2">
<div contenteditable>ddd</div>
<div contenteditable>eee</div>
<div contenteditable>fff</div>
<button onClick="a('save')">SAVE</button>
<button onClick="a('delete')">DELETE</button>
</div>
<div id="3">
<div contenteditable>ggg</div>
<div contenteditable>hhh</div>
<div contenteditable>iii</div>
<button onClick="a('save')">SAVE</button>
<button onClick="a('delete')">DELETE</button>
</div>
And so on.
Using the following function, I can get the clicked button:
function a(value) {
console.log(value);
}
When a button (SAVE or DELETE) is clicked, I need to retrieve:
the id of the "parent" div;
the content of each of the three contenteditable divs inside the same "parent" div.
Is it possible using pure Javascript?
Any suggestion will be very appreciated.
Thanks in advance.
What I would do is implement click listeners in JS, that way I can query elements easily.
Here is the example:
// Query all div.div-editable elements
document.querySelectorAll('div.div-editable')
.forEach((div) => {
// The id of the parent
const divId = div.id;
// Each of content editable divs inside the parent div
const editables = div.querySelectorAll('div[contenteditable]');
// The buttons Save and Delete
const saveBtn = div.querySelector('button.button-save');
const deleteBtn = div.querySelector('button.button-delete');
// Add click listeners to buttons
saveBtn.addEventListener('click', function() {
console.log('Saved: ' + divId);
const contentOfEditableDivs = Array.from(editables).map((div) => div.innerText);
console.log('Values of divs:', contentOfEditableDivs);
});
deleteBtn.addEventListener('click', function() {
console.log('Deleted: ' + divId);
const contentOfEditableDivs = Array.from(editables).map((div) => div.innerText);
console.log('Values of divs:', contentOfEditableDivs);
});
});
<div id="1" class="div-editable">
<div contenteditable>aaa</div>
<div contenteditable>bbb</div>
<div contenteditable>ccc</div>
<button class="button-save">SAVE</button>
<button class="button-delete">DELETE</button>
</div>
<div id="2" class="div-editable">
<div contenteditable>ddd</div>
<div contenteditable>eee</div>
<div contenteditable>fff</div>
<button class="button-save">SAVE</button>
<button class="button-delete">DELETE</button>
</div>
<div id="3" class="div-editable">
<div contenteditable>ggg</div>
<div contenteditable>hhh</div>
<div contenteditable>iii</div>
<button class="button-save">SAVE</button>
<button class="button-delete">DELETE</button>
</div>
EDIT 1: Added code snippet
EDIT 2: Simplified explanation
You can send this keyword in the argument of click's event handler and then access the parent div's id.
So your HTML would look something like:
// rest of the code here
<button onClick="a(this, 'save')">SAVE</button>
<button onClick="a(this, 'delete')">DELETE</button>
// rest of the code here
And your JS code would change to:
function a(elem, value) {
console.log(elem.parentNode.id);
}
More details on the following link:
how i get parent id by onclick Child in js

Why button will not append text from textarea to a panel (Bootstrap)?

I am trying to trigger an event with a button that takes text from a textarea and sends it to a panel using the Bootstrap Framework (v.3.3.7). Currently trying to do this using an event listener in Javascript rather than assigning an ‘onclick’ value for the button.
HTML:
<div class="container-fluid">
<div class="row">
<!-- Panel where text will be appended to -->
<div id="mainChatBox" class="panel-body" style="height:435px; overflow-y:scroll"></div>
<!-- Textarea and button -->
<div class="panel panel-footer" style="height:40px">
<div class="form-group col-md-10 col-lg-10">
<input type="text" placeholder="Type your message here" class="form-control" id="messageBar" />
</div>
<div class="input-group-btn col-md-2 col-lg-2">
<button id="sendMessageButton" class="btn btn-default">Send</button>
</div>
</div>
</div>
</div>
Javascript
var sendMessageButton = document.querySelector('#sendMessageButton');
var messageBar = document.querySelector('#messageBar');
var mainChatBox = document.querySelector('#mainChatBox');
sendMessageButton.addEventListener("click", function (event) {
var message = messageBar.value;
mainChatBox.innerHTML += message + "<br />";
});
I tried debugging by using this code and another version where I instead assign the button an ‘onclick’ value and then keep the function for it.
Here is a link to a reddit post with that version of code where I tried to find a solution with assigning an ‘onclick’ value to the button instead of using an EventListener.
Reddit post link
I need to know why when the event is triggered by the button that the text will not be appended to the mainChatBox when using either the method with the 'onclick' value assignation to the "button" tag for sendMessageButton, or the EventListener in the Javascript.

Angular JS: Change only clicked button text in ng-repeat

I am pretty much new to Angular JS. I have some products to display in the home page which I am displaying using ng-repeat. Each product have an 'Add to cart' button which is also displayed using ng-repeat. My problem is, I want to change the text of a particular button I am clicking. I have used 'toggle' and all the buttons text is changing. Please some one help me with this issue.
My HTML Code:
<div class="col-md-3 col-sm-6" ng-repeat="item in products">
<div class="thumbnail">
<image src="{{item.imageUrl}}"></image>
</div>
<div>
<button class="btn btn-primary" ng-click="toggle(item)">{{buttonText}}</button>
</div>
</div>
My angular js code:
var toggle = false;
$scope.toggle = function(item){
$scope.buttonText = toggle ? 'Add To Cart' : 'Remove From Cart';
toggle=!toggle;
}
You need to add a property to the item you are passing in. Then use that property. Changing scope would change all instances.
var toggle = false;
$scope.toggle = function(item){
item.buttonText = toggle ? 'Add To Cart' : 'Remove From Cart';
toggle=!toggle;
}
<div class="col-md-3 col-sm-6" ng-repeat="item in products">
<div class="thumbnail">
<image src="{{item.imageUrl}}"></image>
</div>
<div>
<button class="btn btn-primary" ng-click="toggle(item)">{{item.buttonText}}</button>
</div>
</div>
kind of like above

Dynamically adding items to HTML list

I'm currently building a wizard in asp.net MVC 5 application using knockout. On one of the steps, I need to add items to an html list. that is, text is enter into a textbox and you click the added button, the text is added to the list.
My template:
<script type="text/html" id="addProduct">
<li class="dd-item bordered-inverse animated fadeInDown">
<div class="dd-handle dd-nodrag">
<div class="checkbox">
<label>
<a data-bind="attr: { 'href': '#' }" class='btn btn-xs icon-only success'><i class="fa fa-trash-o"></i></a>
<label data-bind="text: Name, uniqueName: true"></label>
</label>
</div>
</div>
</li>
</script>
<div class="row">
<div class="col-md-6">
<div id="newProduct" class="dd">
<ol class="dd-list" data-bind="template: { name: 'addProduct', foreach: Model.Step1.ProductServices }"></ol>
</div>
</div>
</div>
input textbox:
#Html.TextBoxFor(model => model.Step1.ProductService, new { data_bind = "value: Model.Step1.ProductService")
<button type="button" id="addservice" data-bind="event:{ click: AddProduct }">Add Service/Product</button>
knockout add event:
self.AddProduct = function () {
self.Model.CurrentStep().ProductServices.push({ name: self.Model.CurrentStep().ProductService });
}
self.Model.CurrentStep().ProductServices is a List Product as just one property name.
The code above add an item to the html list and updates the UI, but self.Model.CurrentStep().ProductServices.length is always zero, meaning nothing was added to the Model itself.
Please how can I force it to update the self.Model.CurrentStep().ProductServices?
length is not a property of an observableArray. Check ProductServices().length instead.

Click button to copy text to another div with angularjs

I have a list of Items with different button with them. Plunker
Quick View:
I want something like if I click on any of the buttons, related text will be copy to the div above. Also if I click on the button again it will removed from the Div.Same for each of the buttons. [I added manually one to show how it may display ]
I am not sure how to do that in Angular. Any help will be my life saver.
<div ng-repeat="item in csTagGrp">
<ul>
<li ng-repeat="value in item.csTags">
<div class="pull-left">
<button type="button" ng-class='{active: value.active && !value.old}' class="btn btn-default btn-xs">{{value.keys}}</button>
<span>=</span>
</div>
<div class="pull-left cs-tag-item-list">
<span>{{value.tags}}</span>
</div>
</li>
</ul>
</div>
The simplest thing would be to use $scope.tags object to store selected tags and add/remove them with the scope method similar to this:
$scope.tags = {};
$scope.toggleTag = function(tag) {
if (!$scope.tags[tag]) {
$scope.tags[tag] = true;
}
else {
delete $scope.tags[tag];
}
};
Demo: http://plnkr.co/edit/FrifyCrl0yP0T8l8XO4K?p=info
You can use ng-click to put in your scope the selected value, and then display this value instead of "Win".
http://plnkr.co/edit/IzwZFtRBfSiEcHGicc9l?p=preview
<div class="myboard">
<span>{{selected.tags}}</span>
</div>
...
<button type="button" ng-click="select(value)">{{value.keys}}</button>

Categories