If value is empty don't add class attr upon append - javascript

http://jsbin.com/guvixara/1/edit
I'm dynamically adding a button...
$(".confirm-add-button").on("click", function() {
var $ctrl = $('<button/>').attr({ class: $('.newbtnclassname').val()}).html($('.newbtntxt').val());
$(".drawing-area").append($ctrl);
UpdateView();
});
However I don't (as in do NOT) want to add the class attribute if the $('.newbtnclassname').val() is blank.
If anyone can help with this it'll be greatly appreciated.

You'd do that like this
$(".confirm-add-button").on("click", function() {
var klass = $('.newbtnclassname').val(),
text = $('.newbtntxt').val(),
obj = {};
if (klass) obj['class'] = klass;
if (text) obj['text'] = text;
$(".drawing-area").append( $('<button />', obj) );
UpdateView();
});
JSBIN

Add this:
$(".confirm-add-button").on("click", function() {
var $ctrl = $('<button/>').attr({ class: $('.newbtnclassname').val()}).html($('.newbtntxt').val());
if($('.newbtnclassname').val() != ""){//add this if statement
$(".drawing-area").append($ctrl);
}
UpdateView();
});
here is the link

You can do that with a simple if condition:
$(".confirm-add-button").on("click", function() {
var $ctrl = $('<button/>').html($('.newbtntxt').val());
var cssClass = $('.newbtnclassname').val();
if (cssClass != "") {
$ctrl.addClass(cssClass);
}
$(".drawing-area").append($ctrl);
UpdateView();
});

Related

dynamically create element with onclick

I'm obviously missing something, but I haven't been able to find what I am doing wrong and I have been staring at this for entirely too long
function message(options) {
...
options.onclose = options.onclose || null;
...
this.gui = document.createElement('div');
this.msg = document.createElement('div');
...
if (options.onclose != null) {
var close = document.createElement('i');
close.innerHTML = 'close';
close.className = 'material-icons close';
close.onclick = options.onclose;
console.log(close.onclick);
this.msg.append(close);
}
this.msg.innerHTML += options.msg;
this.gui.append(this.msg);
...
return this.gui;
}
msgContainer.append(new message({
class: 'update',
sticky: true,
icon: 'mic',
msg: 'You are in a call',
onclose: () => { console.log('click'); }
}));
from the developer console document.querySelector('.close').onclick is null, but if I add an on click document.querySelector('.close').onclick = () => { console.log('click'); }; it works?
Why it wont work is because on click is a function:
document.querySelector('.close').onclick
doesn't do anything so why call it.
document.querySelector('.close').onclick = () {
alert("did something");
}
so the real question is what do you want to do when clicked? create a new link or div.. look below. I would start using jQuery.
jQuery answer:
$(document).ready(function(){
$(".myclass").click(function(){
$(".container_div").append("<a href='test.php'>test link</a>");
// also .prepend, .html are good too
});
});
Here is working example. I changed your code a little bit. You can add more events by passing it to an array. I used addEventListener.
var msgContainer = document.getElementById('msgContainer');
function message(options) {
options.onclose = options.onclose || null;
this.gui = document.createElement('div');
this.msg = document.createElement('div');
if (options.onclose != null) {
var close = document.createElement('i');
close.innerHTML = 'closepp';
close.className = 'material-icons close';
close.dataset.action = 'close';
this.msg.append(close);
}
this.msg.innerHTML += options.msg;
this.gui.append(this.msg);
// Create listeners dynamically later on
events = [
{ selector: close.dataset.action, eventType: 'click', event: options.onclose }
];
renderElement(this.gui, events);
}
function renderElement(element, events) {
msgContainer.append(element);
for (i = 0; i < events.length; i++) {
var currentEvent = events[i];
var selector = element.querySelector('[data-action="' + currentEvent['selector'] + '"]');
selector.addEventListener(currentEvent['eventType'], currentEvent['event'].bind(this), false);
}
}
new message({
class: 'update',
sticky: true,
icon: 'mic',
msg: 'You are in a call',
onclose: () => { console.log('click'); }
});
<div id="msgContainer">
</div>
I finally figured it out! setting innerHTML makes chrome rebuild the dom and in the process it loses the onclick event, onclick works fine if I use textContent instead of innerHTML. In the below example if you comment out the last line of JS the onclick works, here's the same thing in jsFiddle
var blah = document.getElementById('blah');
var div = document.createElement('button');
div.style['background-color'] = 'black';
div.style.padding = '20px;';
div.style.innerHTML = 'a';
div.onclick = () => { alert('wtf');};
blah.appendChild(div);
// Uncomment this to make onclick stop working
blah.innerHTML += ' this is the culprit';
<div id="blah">
</div>

Inline Edit with jQuery UI date picker

I am trying to implement inline edit for the date field (use jQuery UI date picker)
The code I am using is as below;
$(document).on("click",".editableDateTxt", function () {
var currElmModelId = $(this).attr('data-model-id');
var currElmModelAttr = $(this).attr('data-model-attr');
var input = $('<input />', {'type': 'text','name':currElmModelAttr, 'style':'width:100px' ,'data-model-id': currElmModelId, 'data-model-attr': currElmModelAttr, 'class':'datePicker', 'value': $(this).html()});
var parent = $(this).parent();
parent.append(input);
$(this).remove();
input.datepicker().focus();
});
$(document).on("change", ".datePicker", function () {
//alert($(this).val());
var dataValid = $(this).attr('data-valid');
if (dataValid == "Y") {
var currElmModelId = $(this).attr('data-model-id');
var currElmModelAttr = $(this).attr('data-model-attr');
var divEle = $('<div />', {'class': 'editableDateTxt','name':currElmModelAttr, 'data-model-attr':currElmModelAttr,'data-model-id':currElmModelId,'html':$(this).val()});
var parent = $(this).parent();
parent.append(divEle);
$(this).remove();
}
});
$(document).on("blur",".datePicker", function () {
if (this.hasAttribute('data-model-id')) {
var dataValid = $(this).attr('data-valid');
if (typeof dataValid == "undefined" || dataValid == "Y") {
var currElmModelId = $(this).attr('data-model-id');
var currElmModelAttr = $(this).attr('data-model-attr');
var divEle = $('<div />', {'class': 'editableDateTxt','name':currElmModelAttr, 'data-model-attr':currElmModelAttr,'data-model-id':currElmModelId,'html':$(this).val()});
var parent = $(this).parent();
parent.append(divEle);
$(this).remove();
return false;
}
}
});
Now when I select any date or do blur, I get the following error;
Missing instance data for this datepicker
I think the issue is related to the jQuery UI datepicker using data()
So I have tried using detach() instead of remove()...
So I just used $(this).detach();
Could you guide me on the correct way of using detach() which might fix the issue...
You are probably having the same problem I was having. The code in your onblur is firing before the datepicker is completing its work so you are losing the input object before datepicker is done with it.
I was able to resolve this with one of the suggestions in the accepted answer on this question:
https://stackoverflow.com/a/1814308/3434790
The solution that worked in my scenario was to wrap my code inside my on blur function in a setTimeout which effectively made it so that code ran after the datepicker was done doing its thing.
In your case I would suggest the following:
$(document).on("blur",".datePicker", function () {
setTimeout(function(){
if (this.hasAttribute('data-model-id')) {
var dataValid = $(this).attr('data-valid');
if (typeof dataValid == "undefined" || dataValid == "Y") {
var currElmModelId = $(this).attr('data-model-id');
var currElmModelAttr = $(this).attr('data-model-attr');
var divEle = $('<div />', {'class': 'editableDateTxt','name':currElmModelAttr, 'data-model-attr':currElmModelAttr,'data-model-id':currElmModelId,'html':$(this).val()});
var parent = $(this).parent();
parent.append(divEle);
$(this).remove();
return false;
}
}
},100);
});

JavaScript Namespaces + Setter

Well, I'm using object orientation in JavaScript, but instead of using new, I just call the method from the namespace. In the moment, I have the following code:
var Component = {
Button: function(_text, use_image) {
button = $.createElement('button')
if (use_image != false)
{
button.innerHTML = _text;
}
else
{
button.innerHTML = _text
}
var text = _text
return button
}
}
When I want to return a button, I do:
x = Component.Button("Click me")
And after I can use x. But if I want to change the text of x, I must use x.textContent. I'd like to instantiate this and use a setter to apply its text, this way:
x = new Component.Button("Click me")
x.text = "Don't click me"
document.getElementsByTagName("body")[0].appendChild(x)
And if I try to apply the setter text, it becomes global, I want to have a unique for each button. Mix namespaces with get/set.
Thank you in advance
One way can be like, I am not sure if this is the best approach. Looking for more answers
var Component = {
Button: function(_text, use_image) {
var button = {
node : document.createElement('button'),
setText : function(txt){this.node.innerHTML = txt;}
};
if(_text){button.setText(_text);}
return button;
}
};
x = Component.Button("Click me");
x.setText("Don't click me");
document.getElementsByTagName("body")[0].appendChild(x.node);
y = Component.Button("Click me2");
y.setText("Don't click me2");
document.getElementsByTagName("body")[0].appendChild(y.node);
http://jsfiddle.net/2LCyn/
How about something like this:
var Component = (function($){
var buttonCount = 0;
function Button(text, use_image){
this.id = ++buttonCount;
this.text = text;
this.use_image = use_image;
this.$element = $('<button/>').text(text);
this.bindEvents();
}
Button.prototype.bindEvents = function(){
var that = this;
this.$element.on('click', function(){
console.log('hello, I\'m button ' + that.id);
});
};
Button.prototype.setText = function(text){
this.text = text;
this.$element.text(text);
};
return {
Button: Button
}
})(jQuery);
var button1 = new Component.Button('hello', false);
button1.setText('helloooo');
$('body').append(button1.$element);
var button2 = new Component.Button('world', true);
$('body').append(button2.$element);
http://jsfiddle.net/ATmAx/1/

Access javascript object attribute in dynamically generated handler function

I have the following Javascript file, where some html is generated dynamically:
(function ($){
NunoEstradaViwer: {
settings: {
total: 0,
format: "",
num: 0;
},
init: function (el, options) {
if (!el.length) { return false; }
this.options = $.extend({}, this.settings, options);
this.itemIndex =0;
this.container = el;
this.total = this.options.total;
this.format = ".svg";
this.num = 0;
this.generateHtml(el);
},
generateHtml: function(container){
var bnext = document.createElement('input');
bnext.setAttribute("type", "button");
bnext.setAttribute("id", "bnext");
bnext.onclick = this.nextImage();
bnext.setAttribute("value", "Next");
container.appendChild(bnext);
},
nextImage: function(){
this.num++;
}
});
What I wanted to do was to access the NunoEstradaViwer attribute num inside the nextImage function but instead the this object points to the bnext button.
Do you know how I can manage that?
check the link
bnext.onclick = this.nextImage; // not bnext.onclick = this.nextImage();
another thing is
NunoEstradaViwer.num++ ; // instead of this.num++
#rahen, I tried your sugestions but unfortunately none worked.
What I found out that worked for me was a solution envolving jquery. I did the following:
generateHtml: function(container){
var bnext = document.createElement('input');
bnext.setAttribute("type", "button");
bnext.setAttribute("id", "bnext");
bnext.setAttribute("value", "Next");
container.appendChild(bnext);
$("#bnext").bind('click',{viewer: this}, function(event) {
event.data.viewer.nextImage();
});
},
nextImage: function(){
this.num++;
}
And this way I can access the value of num and it is changed for the NunoEstradaViwer.

trying to remove and store and object with detach()

I am trying to remove an object and store it (in case a user wants to retrieve it later). I have tried storing the object in a variable like it says in the thread below:
How to I undo .detach()?
But the detach() does not remove the element from the DOM or store it. I am also not getting any error messages. Here is the code I am using to detach the element:
function MMtoggle(IDnum) {
var rowID = "row" + IDnum;
var jRow = '#' + rowID;
thisMMbtn = $(jRow).find(".addMMbtn");
var light = false;
var that = this;
if (light == false) {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
$(this).unbind("click");
light = true;
}
);
}
else {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
thisMM = thisRow.find(".mmCell");
SC[rowID].rcbin = thisMM.detach(); //here is where I detach the div and store it in an object
$(this).unbind("click");
light = false;
}
);
}
}
MMtoggle(g.num);
A fiddle of the problem is here: http://jsfiddle.net/pScJc/
(the button that detaches is the '+' button on the right. It is supposed to add a div and then detach it when clicked again.)
Looking at your code I don't think so you need detach for what you are trying to achieve.
Instead try this code.
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var $mmCell = thisTxt.find('.mmCell');
if($mmCell.length == 0){
$mmCell = $('<div class = "mmCell prep"></div>')
.appendTo(thisTxt).hide();
}
$mmCell.toggle();
//$(this).unbind("click");
}
);
Demo

Categories

Resources