How to dynamically generate html widgets using jQuery? - javascript

I have an interactive widget that I want to display on my page. However I also want to give the user the possibility to generate more instances of the same widget and to be able to interact with them simultaneously. As an example, let's say this is my widget:
<div id="my_widget">
<script type="text/javascript" src="jquery-1.5.1.js"></script>
<script>
$(document).ready(function() {
$("#up_one").click(function() {
$("#number").val(parseInt($("#number").val())+1);
});
});
</script>
<p>
<input type="submit" id="up_one" value="Up One!"/>
<input type="text" id="number" type="number" value="0" maxlength="2">
</p>
</body>
Now, to display this on my main page I use load(), as follows
$(document).ready(function() {
var i = 0;
$("#hello_submit").click(function() {
$("#hello_div").load("widget_test.html");
});
});
</script>
<div id="hello_div">
<p>
<input id="hello_submit" type="submit" value="New counter" />
</p>
</div>
But there are 2 problems with this. First I can only load the widget once, and second, it would allow the user to navigate directly to widget_test.html, which would defeat the purpose of all this. So I tried another method that involves turning the widget into a long string. To this string I add an index parameter which is used to dynamically generate id and class names, like this:
function BAString(){
this.getBas = function(value){
var bas = '<body><script>$(document).ready(function() {$("#up_one'+value+'").click(function() {\
$("#number'+value+'").val(parseInt($("#number'+value+'").val())+1);});}); </script> <p>\
<input type="submit" id="up_one'+value+'" value="Up One!"/>\
<input type="text" id="number'+value+'" type="number" value="0" maxlength="2"></p></body>';
return bas;
};
In my main page I then use this function:
$(document).ready(function() {
var i = 0;
$("#hello_submit").click(function() {
var b = new BAString();
$("#hello_div").append(b.getBas(i));
i++;
});
});
This second method seems to work great but I can see obvious problems with maintainability as my widget becomes more and more complex. So what is the ideal solution to be used in a case like this?

Well you can make it work with classes instead of Ids
that way you can add multiple widgets with the same function
$(document).ready(function() {
$(document.body).on( "click", ".up_one" ,function() {
$x = $(this).siblings('.number');
$x.val(parseInt($x.val())+1);
});
});
Here's a fiddle that works with just adding HTML
If you want to modify the widget in the future you could just load the external html instead of creating it

Related

How would I go about creating this jump page?

Note: I'm a total novice at any coding. I'm just a dumb amature graphic designer. I've only ever created a page that lets me copy the
the most common phrases I had to leave in notes all day. I struggled
with it.
I'm trying to create this page that lets input something into a text field, and it applies it to defined URLS attached to buttons, that will bring me to those pages. Since I struggle to describe it, please see this visual: https://i.stack.imgur.com/ZplRK.jpg
I've tried co-opting some scripts for similar problems, but with no luck. (See below for examples before I edited them ). I included them to see if I was on the right track whatsoever. I know I'm gonna have an issue with multiple functions, probably?
<script type="javascript">
function goToPage(var url = '')
{
var initial = "http://example.com";
var extension = "html";
window.location(initial+url+extension);
}
</script>
<form name="something" action="#">
Label <input type="text" name="url" value="" onchange="goToPage(this.value)">
</form>
<SCRIPT type="javascript">
function goToPage(var url = '')
{
var initial = "https://cms.example.com/client/viewcasedetails";
var extension = "";
window.location(initial+url+extension);
}
</SCRIPT>
<TITLE>Redirect 1</TITLE>
<BASE HREF="https://cms.example.com/client/viewcasedetails">
</HEAD>
<BODY>
<P>
<FORM name="jump" action="#">
CMS ID:
<INPUT type="text" name="url" value="" onSubmit="goToPage(this.value)">
<INPUT type="submit" value="GO">
That's where I at. I'm just tired of typing the same long URLs all day at work, and messing up more than half the time. I have no clue what the solution is - Javascript? HTML? CSS? Just trying to seek the DIY answer before looking on how to hire someone to make it. Which I have no clue how to do either but that's another question for later.
Thanks for helping / apologies for possibly super dumb questions.
You could do something like the following:
// grab the input element
const input = document.getElementById("cmsId");
// grab all links that need to be updated accordingly
// when value inside input element changes
const links = document.querySelectorAll("a");
// create a handler that listens for changes when
// you type some text into the input element
input.addEventListener("input", (event) => {
// grab value inside input elemenet
const value = event.target.value;
// iterate through all links and update
// the inner text + href attribute accordingly
// NOTE: `baseUrl` for each link is stored in a
// `data-*` attribute
links.forEach((link) => {
const baseUrl = link.dataset.url;
const url = baseUrl + value;
link.innerText = url;
link.href = url;
});
});
<!-- Use a simple input element here, no need for a form -->
<div>CMS ID: <input id="cmsId" type="text" /></div>
<div>
<!-- No need to create buttons, simple anchor elements will work just fine -->
<a
id="main"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/viewclientdetails/"
>
https://cmss.company.com/client/viewclientdetails/
</a>
</div>
<div>
<a
id="notes"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/viewnotes/"
>
https://cmss.company.com/client/viewnotes/
</a>
</div>
<div>
<a
id="docs"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/documentsall/"
>
https://cmss.company.com/client/documentsall/
</a>
</div>
<div>
<a
id="activity"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/viewactivityledger/"
>
https://cmss.company.com/client/viewactivityledger/
</a>
</div>
In your code you are working with only the "main" button as I can see (as it goes to viewclientdetails). You are missing a "/" sign after var initial. So, assuming that you can implement the same functionality of the main button to the other buttons, here's what you can do:
<script type="text/javascript">
function goToPage(var url = '')
{
var initial = "https://cms.example.com/client/viewcasedetails/"; //I added the slash
var extension = "";
window.location(initial+url+extension);
}
</script>
<TITLE>Redirect 1</TITLE>
<BASE HREF="https://cms.example.com/client/viewcasedetails">
</HEAD>
<BODY>
<P>
<FORM name="jump" action="#">
CMS ID:
<INPUT type="text" name="url" value="" onSubmit="goToPage(this.value)">
<INPUT type="submit" value="GO"> //you need 4 buttons here
You cannot have an input type="submit" here, since you will need four buttons. Submit works like a form submission. Add four buttons, then for each button's onClick property add the desired redirect url. You will need to get the value for the input field using an ID tag.
An example of what I am trying to say is given below:
<script type="text/javascript">
function onMainButtonClicked()
{
var cmsid= document.getElementById("cmsID").value;
var initial = "https://cms.example.com/client/viewcasedetails/"; //I added the slash
var extension = "";
window.location(initial+cmsid+extension);
}
function onNotesButtonClicked()
{
...
}
function onDocsButtonClicked()
{
...
}
function onActivityButtonClicked()
{
...
}
</script>
<TITLE>Redirect 1</TITLE>
<BASE HREF="https://cms.example.com/client/viewcasedetails">
</HEAD>
<BODY>
<P>
<FORM name="jump" action="#">
CMS ID:
<INPUT type="text" id="cmsID" name="url" value="">
<button onclick="onMainButtonClicked()">Main</button>
<button onclick="onNotesButtonClicked()">Notes</button>
<button onclick="onDocsButtonClicked()">Docs</button>
<button onclick="onActivityButtonClicked()">Activity</button>
There are much better ways to implement this, but this is a very simple implementation.

How do i add custom code from a user inside the <head> tag

i created a form builder, however, i need to find a way to have the person add their own tracking codes when they publish the forms, these tracking codes go in the code.
<section class="tracking-codes">
<h2> Please enter all tracking codes in here: </h2>
<form>
<input type="text" id="code" placeholder="Facebook Pixel"> </input>
<button type="button" onclick="codes()"> Add Code </button
</form>
</section>
here is my js
function codes ()
{
var trackingCode = document.getElementById('code');
document.head.appendChild(trackingCode);
console.log(trackingCode);
}
at this point, it does append the id of code but only the part of
<input type="text" id="code" placeholder="Facebook Pixel">
and not the user input, how would i go about doing this?
I have also tried the .value at the end of making the var of trackingcodes but it doesnt work.
Instead of adding html to the head section, you should use a hidden field input. Add it like this:
function codes ()
{
var trackingCode = document.getElementById('code').value;
var element = document.createElement('input');
element.type = 'hidden';
element.id = 'tracking';
document.head.appendChild(element);
console.log(trackingCode);
}

Show/hide angular element by condition

I built a feature adding "and zombies" to book names of choice, using basic angular.
<input type="text" ng-model="bookname" onclick="zombies()">
<h1> {{bookname}} </h1>
I want the "and zombies" (and the text inserted in the input) to be displayed only when there's text inside the input.
I tries this for starts, just to call the angular using JS and it doesn't work.
<script>
function zombies() {
document.getElementsByTagName("h1").innerHTML = "{{}}" + "and zombies";
};
</script>
How do I display the text when there's text inside the input?
(please go easy on me, I'm studying alone and you all started as juniors)
You Just need to add the condition which checks the value of bookname and display the static content with your name.
Like this -
<input type="text" [(ngModel)]="bookname" (click)="zombies()">
<h1> {{bookname}} <span *ngIf='bookname'>and zombies</span> </h1>
You can use a condition here.
<input type="text" [(ngModel)]="bookname" onclick="zombies()">
<h1 *ngIf="bookname"> {{bookname}} and zombies</h1>
Or if you want to use javascript:
<input type="text" ng-model="bookname" onclick="zombies()">
<h1 id="txtheading"></h1>
function zombies() {
var heading_value = document.getElementById("txtheading").value;
document.getElementById("txtheading").innerHTML = heading_value + " and zombies";
};
Easiest Solution you don't need onclick function ng-model will work itself.
AngularJs:
<input type="text" ng-model="bookname">
<h1>{{(bookname)? bookname+' and zombies' : bookname}}</h1>
Angular 2/4/5/6:
<input type="text" [(ngModel)]="bookname">
<h1>{{(bookname)? bookname+' and zombies' : bookname}}</h1>

javascript add button with two input

I'm trying to write this in javascript without using jquery. It basically has two input field: author and quote, and on click should be added to the page.
I'm also trying to save it on the page in case I leave the page. The added quote disappears when i execute the method:
function radd() {
if((document.getElementById("q").value!="") && (document.getElementById("a").value!="")) {
$("#mid-wraper" ).append("<p class='left-bullet'>"+document.getElementById("q").value+"-<span class='yellow-heading'>"+ document.getElementById("a").value+"</span></p>");
document.getElementById("q").value="";
document.getElementById("a").value="";
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="but" onClick="radd()">Add</button>
<label for="q">Add ur Quote!</label><input id="q" name="q" />
<label for="a">The author name</label><input id="a" name="a" />
Try this
function radd()
{
if((document.getElementById("q").value!="")&& (document.getElementById("a").value!=""))
document.getElementById("mid-wraper").innerHTML += "<p class='left-bullet'>"+document.getElementById("q").value+"-<span class='yellow-heading'>"+ document.getElementById("a").value+"</span></p>";
document.getElementById("q").value="";
document.getElementById("a").value="";
}
function add(){
//create a new elem
var el=document.createElement("p");
//you can assign id, class , etc
el.id="yourcustomid";
el.textContent="yourcontent";
//then add to the wrapper
var wrapper=document.getElementById("mid-wrapper");
wrapper.appendChild(el);
}
This code shows you how to create a new paragraph and add it to your wrapper js...
You could also do something like this; far more easier in my opinion. Simply create both inputs, but set their attributes to hidden. And using javascript, delete the "hidden" attribute.
<button id="but" onClick="radd()">Add</button>
<input id="q" hidden="hidden" >Add ur Quote!</input>
<input id="a" hidden="hidden">The author name</input>
The JS part:
function radd(){
document.getElementById("q").removeAttribute("hidden");
document.getElementById("a").removeAttribute("hidden");
}

How to create a tree structure in Javascript DOM?

This is going to sound too silly / too basic - sorry about that, but I experimented a lot and couldn't come to the right solution!
I'm using this following piece of code - which makes a row of text fields go up and down. Unfortunately, the up and down movement doesnt stop and carries on throughout the page! :)
function up(row) {
// need to stop somewhere
var prevRow = row.previousSibling;
if(prevRow != null) {
row.parentNode.insertBefore(row, prevRow);
}
};
function down(row) {
// need to stop somewhere as well
var nextRow = row.nextSibling;
row.parentNode.insertBefore(row, nextRow.nextSibling);
};
My generated html is a combination of xml and xsl. The XSL looks like this:
<xsl:for-each select=".../...">
<p>
<button type="button" onclick="up(this.parentNode)">Up</button>
<button type="button" onclick="down(this.parentNode)">Down</button>
<input>
...
...
...
</p>
</xsl:for-each>
As described above, this works, but the up and down movements dont stop. I tried enclosing the xsl:for-each in another p tag, and a div tag, but neither worked. I was trying to have the parent of these p tags as something other than the body tag.
Did I make myself clear?
Generated HTML added below:
<html>
<head>
<script>
function up(row) {
...
};
function down(row) {
...
};
</script>
</head>
<body>
<form name="edit_form" action="edit.php" method="POST">
...
<?xml version="1.0"?>
...
<p>
<button type="button" onclick="up(this.parentNode)">Up</button>
<button type="button" onclick="down(this.parentNode)">Down</button>
<input name="CRorder[record10354881]" type="text" value="0" disabled="" size="4"/>
<input name="CRpreference[record10354881]" type="text" value="10" disabled="" size="4"/>
<input name="CRlabel[record10354881]" type="text" value="label1"/><input name="CRvalue[record10354881]" type="text" value="22222222222"/></p>
<p><button type="button" onclick="up(this.parentNode)">Up</button>
<button type="button" onclick="down(this.parentNode)">Down</button>
<input name="CRorder[record10354882]" type="text" value="1" disabled="" size="4"/>
...
...
</form></body>
</html>
Based on your HTML, and assuming the ...s do not contain matched pairs of tags that will make the P a child, the P containing the Up/Down buttons (and other paraphinalea) will move up the list of Ps until it is the first child of the FORM tag. As this is directly adjacent to the BODY tag, this is, in effect, moving it all the way up the page.
Edit: OK, from your comment, if you have other siblings to the P tags that you don't to move them past, you'll need to mark them somehow and change your up/down functions to obey those limits. Something like...
...<tag id="upperLimit">...
function up(row) {
// need to stop somewhere
var prevRow = row.previousSibling;
if(prevRow != null && prevRow != document.getElementById("upperLimit")) {
row.parentNode.insertBefore(row, prevRow);
}
};
with a similar restriction on the lower limit.

Categories

Resources