How to make a dynamic javascript class. - javascript

another question! I am using Ajax to get the updated Billing Domain ID that is associated with the OfficeId Dropdown.
I have the need for an if statement that is changed dynamically. Here is what I am trying to accomplish.
I want for certain fields to be hidden based on the BillingDomainID. For example, if BillingDomainID is 1, I want to hide the fields. The trick is that I want to be able to expand as time goes on so that it can also be used for other IDs as they arise.
Here is what I have so far without any success.
function getOfficeInfo(OID, BDID) {
//alert(OID);
//alert(BDID);
$.post("/UserControls/getOfficeInfo.asp", {OfficeID: OID}, function(data) {
BDID.val(data);
var vBDID
vBDID = ".BillingDomainID" + data;
//alert(vBDID);
if (data != 1) {
$(vBDID).hide();
}
});
//alert(data);
}
I am just needing to know how to make the $(vBDID).hide(); part work.

There are so many ways to go about this, since you have control over the HTML I think you have two direct approaches:
Create a map of fields to Billing Domains Ids
var fieldMap = {
'1': ['first-name', 'last-name', ...],
'2': ['first-name', 'last-name', 'ssn', ...],
...
};
Then you can do something like (assuming data is the billing domain id:
var $form = $('form');
// hide everything by default
$form.find('input').hide();
// show all fields that pertain to this domain
$form.find(fieldMap[data].map(function(field) {
// gives you '[name="first-name"]'), etc.
return '[name="'+field+'"]';
})).show();
Add class names to inputs to indicate which billing domain ids they are shown for
<input type="text" name="first-name" class="domain-1 domain-2 domain-3" />
And then:
$form.find('.domain-'+data).show();
Though I feel like that could get kind of messy if you have a lot of domains.

I'm not sure why your element isn't hiding unless your typing your class name incorrectly. Here's a fiddle that shows how this works.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="someClass" type="button">
Hi there
</button>
$(function(){
var thing = '.someClass';
$('button').on('click', function(){
$(thing).hide();
})
});

Related

How to add HTML code to a different HTML file using JavaScript or PHP

Alrighty, so I am trying to make a little page on my website that takes a few values and then when you click a button, it adds those values inside of a div on a different HTML page.
My code is:
<input type="text" name="URL"><br>
<input type="text" name="ImageURL"><br>
<input type="text" name="Title">
<button onclick="addCode()">Submit</button>
So for the addCode() function I want it so that it adds the values inside of a the item div on a different HTML file just like:
<div class="item">
<div class="animate-box">
<a href=URL><img src=ImageURL></a>
<div class="fh5co-desc"><a style="TEXT-DECORATION:none; COLOR:#818892; LINE-HEIGHT:20px;" href=URL>Title</a></div>
</div>
</div>
Thanks in advance.
What you are doing is technically impossible. without some sort of persistence, that is;
you cannot edit a page you aren't on. web browsing is a stateless technology.
if you meant you want to fill out those inputs then redirect on click and have those values available, there are a few different ways to do it:
1) Query String
write your code on the second page in a way that it accepts params from a query string in the url bar
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
var textDecoration = getUrlParameter('textdec'),
color = getUrlParameter('color'),
lineHeight = getUrlParameter('lnheight');
then you can send the request for the page as
http://page.com/page?textdec="someval"&color="somecolor"&lnheight="someheight"
however this will not work if you are not going directly to that page after your current one
2) localStorage
on your first page set the local storage values:
localStorage.setItem('lineHeight', 'someVal');
localStorage.setItem('color', 'someColor');
localStorage.setItem('textDecoration', 'someVal');
then on your second page retrieve the values
var lineHeight = localStorage.getItem('lineHeight'),
color = localStorage.getItem('color'),
textDecoration = localStorage.getItem('textDecoration');
3) serverSide persistence
this will vary MASSIVELY depending on how you your backend is structured
but the general gist is make a post request (ajax or otherwise) &
collect the data on the backend
then when you render the second page send the variables that were posted, either through interpolation or included as script variables
The only way to do this (without getting other technologies involved) is to use the localStorage, storage event. And, even with this, it will only work when the two pages are coming from the same domain and are open in different browser tabs (of the same browser) at the same time.
If those conditions are present, then modifying localStorage on one page will fire the storage event, which the other page can be set up to listen for. The other page can then respond to the event by pulling new values (that the first page wrote into localStorage) out and placing them anywhere on the second page that you like.
This is the kind of solution that you might encounter if you were on a travel site with more than one browser tab open. You may be looking at different flight options in different tabs. If one tab's code has an update that any/all other open tabs should know about, this technique does the trick.
Here's an example of how to set values into localStorage and use them. But, localStorage doesn't work here in the Stack Overflow snippet environment, so you can run the code here.
Once the values are in localStorage, you can pick them up from any other page that is being served from the same domain. So, the "getItem" code I'm showing here would really be placed on your "page2.html".
// Get DOM references:
var name = document.getElementById("name");
var color = document.getElementById("color");
var airspeed = document.getElementById("airspeed");
var btn = document.getElementById("btnGo");
// Set up button click event handler:
btn.addEventListener("click", function(){
// Get values and place in localStorage
localStorage.setItem("name", name.value);
localStorage.setItem("color", color.value);
localStorage.setItem("airspeed", airspeed.value);
// For demonstration, get values out of localStorage
console.log("What is your name? ", localStorage.getItem("name"));
console.log("What is your favorite color? ", localStorage.getItem("color"));
console.log("What is the airspeed of a laiden swallow? ", localStorage.getItem("airspeed"));
// If you wanted to redirect the user to the second page, now that the intial values
// have been set, you could just do:
location.href = "path to second page";
});
<div>What is your name?<input type="text" id="name"></div>
<div>What is your favorite color?<input type="text" id="color"></div>
<div>What is the airspeed of a laiden swallow?<input type="text" id="airspeed"></div>
<button id="btnGo">Go!</button>
If you're trying to edit the actual source code of the file, you'll need something like PHP. Otherwise, JS is just fine.
PHP Solution
You could use something like this:
<?php
$old = file_get_contents("some_page.html");
$content = explode("<span>",$old,2); // replace <span> w/ opening tag
$content = explode("</span>",$content[1],2); // replace </span> w/ closing tag
$data = "new content of element";
$new = str_replace($content[0],$data,$old);
?>
Updated JS Solution
You can't use my previous solution. Instead, you would have to create a function in the second HTML file that could be called from the first file, like this:
A script in file2.html:
function set(id,val){
$("#"+id).html(val); // jQuery
document.getElementById(id).innerHTML = val; // pure JS
}
A script in file1.html:
var win = window.open("http://example.com"); // open the window
win.set("some_id","Some content.") // the function that we set earlier
Note that this is reverted once the user closes or reloads the tab, and only applies to that user and that tab.

How do I create 5 JQuery AJAX calls using eventhandlers?

I am developing a registry system for my school/workplace, and the instructors need a thorough list of the students who fall into 5 separate categories:
Have not met and have not registered absence
Have not met but registered absence after 8 am
Have not met but registered absence before 8 am
Have met but registered reason for absence after 8 am
Have met and registered before 8 am
As the first one (Have not met and not registered) will be loading student data across 3 databases for checkup, getting the data might take some time. I figured instead of loading all the data through PHP, displaying a white screen to the user until everything is loaded, instead I would load the page and then get the data using JQuery AJAX functions.
The AJAX loading and displaying works using this code:
//Not met and not registered
div1 = $("#not-met-not-registered");
div1.find(".text").html("<img src='' class='loader'>");
$.post("/admin_post/getusers", {area:"not-met-not-registered"}, function(data) {
div1.find(".text").html(data);
div1.find("tr").each(function (row) {
datatable1.push({
"Row": $(this),
"Navn": $(this).find("td.navn").html()
});
});
});
However, this only works as I staticly input the div value, and save the div value in 5 different names (div1, div2 etc.).
To receive the data, I have 5 divs looking like this:
<div id="not-met-not-registered" class="list">
<label>Students who have not met and not registered absence</label>
<img src="/images/search.png" class="search">
<input type="text" class="search">
<div class="text"></div>
<input type="button" value="Print">
</div>
Each div has the unique id that AJAX should send via POST to get the liable data. Which is why I figured something along the lines of this would be applicable:
$("div.lists div.list").each(function() {
$(this).on("ready", {div: this}, function (eventObject) {
div = eventObject.data.div;
$.post("/admin_post/getusers", {area: $(div).attr("id")}, function (data) {
div.find("div.text").html(data);
div.find("tr").each(function (row) {
datatable.push({
"Row": $(this),
"Name": $(this).find("td.name").html()
});
});
});
});
});
The function would save the div in question inside the eventObject.data array, and use the id of that div as search criteria on the PHP page. By saving the div as a value in the eventObject, I would be able to use the same name other places I figured, since, as seen below, that idea worked for my search function using eventhandlers.
Each table is given their own search opportunity using a functional eventhandling code, though not yet built for the full purpose:
$(this).find("input[type=text].search").on("change", {preVal: ""}, function (eventObject) {
preVal = eventObject.data.preVal;
curVal = $(this).val();
if (preVal != curVal) {
eventObject.data.preVal = curVal;
alert(curVal);
}
});
I am aware that I am not a very skilled JS or JQuery coder, and perhaps I am going way out of best practice or missing something very obvious. I really hope you can help me out anyway though!
I managed to find out what the fault was, and figure I would post it here.
So, for some reason, when you call a function in JQuery and save a variable in it, the next time you call the same function and save a new value in the variable, the new variable is saved in the old function call.
Right now I save the element e in div
div = e;
When I call it 5 times:
div = 1
div = 2
div = 3
div = 4
div = 5
Then, when the AJAX returns, what it sees is this:
div = 5
div = 5
...
By removing the div part of it, I made it work:
function load_in(e, link, target, data)
{
$.post(link, {data:data}, function(data) {
$(e).find(target).html(data);
enable(e);
setCount(e);
});
}
This function takes the e-lement, the link you AJAX to, the Target that you want your result to go into and whatever data you wish to send as POST data
Callable with this:
load_in(this, "/admin_post/getusers", "div.list", $(this).attr("id"));

CKEditor SetData JQuery

I have a DropDownList where onChange sets the content of the TextArea which is my CKEditor control.
When the editor is not in use I run this bit of code for onChange:
$(".setBody").change(function() {
//
var className = "." + $(this).attr("sExternalId");
var text = $(this).val();
//
$(className).val(text);
});
I'm not very experienced with Javascript/JQuery and I just can't figure out how to perform the same using CKEditor's setData() function. This is what I've tried:
$(".setCKBody").change(function() {
//
var className = "." + $(this).attr("sExternalId");
var text = $(this).val();
//
var editor = $(className).ckeditorGet();
editor.setData(text, function() {
alert("The content was set");
});
});
$(".setCKBody").change(function() {
//
var className = "." + $(this).attr("sExternalId");
var text = $(this).val();
//
CKEDITOR.instances[$(className)].setData(text, function() {
alert("The content was set");
});
});
Am I close? I think one of the main limitations is that I have multiple editor controls with the same id and name, only the class can tell them apart which is why I'm using that with the JQuery. I've tried working through some examples online, but I'm not sure how to apply them to this scenario - that's probably my inexperience coming through there...
Thanks.
EDIT
This is how my textarea and dropdownlist appears in view source:
<textarea class="editArea M3" cols="20" id="Body" name="Body" rows="5">
*some text*
</textarea>
<select class="setCKBody" id="Templates" name="Templates" sExternalId="M3">
<option value="some value">Option 1</option>
<option value="some value">Option 2</option>
</select>
The onChange event above is triggered from the dropDownList changing and is linked to the textArea via the "sExternalId" attribute. I realised I used "id" as the attribute name in the example above which was in error, so I changed that.
I use this to set it as a CKEditor control:
<script>CKEDITOR.replaceAll('editArea');</script>
I have between 2 to 6 textarea controls on the same page, created with razor like this:
#Html.TextAreaFor(m => m.Body, new { #class = "span12 editArea " + Model.ExternalId, rows = 5 })
They are contained within a partial view that is used like this:
#foreach (MailTemplateModel oTemplate in Model.Templates)
{
#Html.Partial("_MailPartial", oTemplate)
}
This is why each text area has "Body" set as the id and name. I think this is the heart of the problem, with there being multiple elements with the same id and name CKEditor is not able to select the correct one. I've tried to do CKEDITOR.instances["className"] but that was undefined, whereas doing CKEDITOR.instances.Body did work, but would only ever return the same value.
I'm going to restructure the way the page is created to avoid this, hopefully my issues will be solved at the same time.
Here's a few pointers.
Use class="foo" if you have many things that you refer to as a group, like like here it looks like you would have many setCKBody elements you listen to for change events.
Use id="foo" if you have one single specific thing.
Using the same id and class for one element usually is not the right thing to do.
CKEDITOR.instances[xxx] <-- xxx should be a string, not a jquery object - so CKEDITOR.instances[className] might work better (I can't say not having seen your HTML).
It would help if we saw your HTML; textarea definitions and setCKBody definitions. Do you have many ckeditors and many setCKBody elements?
My original approach to this scenario was all wrong, I had a model that contained multiple mail templates and so I rendered each one via a partial view within the same page so that the user could click to edit any one of them and the details would appear in a modal popup - within the same window. What I wanted to avoid was forcing the user to navigate to another window to edit a mail template, but this lead to multiple elements having the same id and name attributes which prevented me from accessing them correctly.
I've now added a list box where the user can select a template to edit, the selected template is rendered underneath and so avoids the multiple name and id issue. Now I know there is only ever 1 CKEditor control so I can access it in my js like this:
var editor = CKEDITOR.instances.SelectedTemplate_Body;
SelectedTemplate_Body is the name and id of the element I made into a CKEditor control. The onChange function I wrote for the dropdownlist is now written like this:
$(document).ready(function() {
//
$(".setBody").change(function() {
//
var templateId = $(this).val();
//
$.ajax({
type: "GET",
url: msHost + "MailTemplates/UpdateBody",
data: { "templateId": templateId },
cache: false,
dataType: "text",
success: function (data) {
CKEDITOR.instances.SelectedTemplate_Body.setData(data);
}
})
});
});
The tempalteId attribute is the value associated to the dropdownlist selection, this lets me know which template to use for setting the content of my editor control.
MailTemplates/UpdateBody points to a public method in my MailTemplates controller which runs a search on available mail templates and matches against the template Id passed in, the method then returns the body of the template as a string.
public string UpdateBody(string tempalteId)
{
TemplateQuery oQuery;
//
oQuery = new TemplateQuery();
oQuery.Execute();
foreach (MailTemplate oTemplate in oQuery.Results)
if (oTemplate.Id.Equals(templateId))
return oTemplate.Body;
//
return string.Empty;
}
This line replaces the contents of the CKEditor control with the response from the controller method.
CKEDITOR.instances.SelectedTemplate_Body.setData(data);
Thanks #Nenotlep for trying to help out, you gave me a few things to think about there.

dynamically created form depending on <select> does not work

I'm developing a website which must display particular forms for various products depending on the value that the user selects (in <select>) - so a number various forms are created dynamically in a loop by means of a javascript function (buildform() ). The code does not work, e.g. the forms are not created/appended to the wrappers. I narrowed down the problem where i think the problem relates to a different values for the jquery selectors/div-id's (#ecorpproductwrapper"+ecorp_eprodselectid).
When I use (just as a test) #ecorpproductwrapper" (without the variable ecorp_eprodselectid; see also in code below under ALTERNATIVE WORKS) the code works fine, e.g. the forms are built. I checked by means of the console that the ecorpproductwrapper"+ecorp_eprodselectid values are the same for the div-id's and jquery selectors, so I dont understand what goes wrong?
Pls see the simplified code below:
for(var i=0;i<5;i==){
var ecorp_eprodselectid; //will have various values
//function to build form depending on selected value in <select class= eprodtype"+ecorp_eprodselectid >
$(".eprodtype"+ecorp_eprodselectid).focus(function () {
var previous;
// Store the current value on focus and on change
previous = this.value; //old select value
}).change(function() {
var optionsform = buildform(this.value);
console.log('append form'+optionsform);
//NEXT 2 lines doe NOT WORK
$("#ecorpproductwrapper"+ecorp_eprodselectid).children().remove(); //remove previous form
$("#ecorpproductwrapper"+ecorp_eprodselectid).append(optionsform);
//ALTERNATIVE works: $('#ecorpproductwrapper').children().remove(); //remove previous tariif struct form
//ALTERNATIVE works: $('#ecorpproductwrapper').append(optionsform);
var str = "#ecorpproductwrapper"+ecorp_eprodselectid;
console.log('STRING ECORP PRODUCT APPEND: '+str);
console.log('change eprod val: '+this.value);
previous = this.value;
});//$("").focus(function () {
}//for i
//function to build form
var buildform = function(ecorp_eproductid) {
//some code here
//NEXT LINE does not work:
form += '<td> <div id="ecorpproductwrapper'+ ecorp_eprodselectid+'"> </div> </td> </tr>'; //cell with wrapper for ecorp product info
//ALTERNATIVE WORKS: form += '<td> <div id="ecorpproductwrapper"> </div> </td> </tr>'; //cell with wrapper for ecorp product info
//some code here; returns form
}//function buildform
I think you forgot to add ecorp_eprodselectid in your function.
var buildform = function(ecorp_eprodselectid ) {
Few things we assume concerning given text above:
You know this.value works
console.log shows optionsform have HTML that it should have. Not said in OP but if not, the function does not work. function seems to be missing already var buildform = function(someVar) as noted by buysDB
As I cannot see your code, I would try first clear everything 100% by chaning this:
$("#ecorpproductwrapper"+ecorp_eprodselectid).children().remove();
to:
$("#ecorpproductwrapper"+ecorp_eprodselectid).html("");
Then:
$("#ecorpproductwrapper"+ecorp_eprodselectid).html(optionsform);
No need for append if you have no intention to keep anything in DIV.
If you have text also in (#ecorpproductwrapper"+ecorp_eprodselectid) which is why you use children(), consider selecting the DIV that can be cleared.
If that still does not work, something is left out that needs consideration.

Add to favorites, jquery

I am creating a 'favorites' style system for a property webiste where users can save a property to be viewed later. The system works using Jquery so the page doesn't have to refresh. The details page of a property contains a 'add to favorites button' and this works fine:
$("#addFavorites").click(function() {
var locationID = $("#locationID").val();
But how would I code this when all of the properties are listed together on one page, each 'add to favorites' button would have to use a unique id or something but not sure how to approach this.
Well the most precise way would be a default HTML-Formular. I'll make it a short one:
<form ...>
<label for="fav1">Fav1</label>
<input type="checkbox" name="favorites[]" id="fav1" value="1" />
<label for="fav2">Fav2</label>
<input type="checkbox" name="favorites[]" id="fav2" value="2" />
<submit>
</form>
Now that's the ugly form, you can make this beautiful with CSS. With jQuery you now always submit the form when the user checks any of the checkboxes, like:
$('input[type=checkbox]').change(//do ajax submit);
In the AJAX File you simply read the array:
foreach($_POST['favorites'] as $fav) {
addFavToUser($fav, $user);
}
This is like simply explained to give you an idea, not the whole "clean" solution. But i hope this helps you - if it does, i always appreciate the vote for it ;)
Each of your 'favorites' would need a unique id
...
...
Then..
$('.favorite').click(function(){
$(this).whateveryouwanttodo();
});
$(this) will contain the clicked anchor tag. from that you can get the id, and call your ajax post or whatever you want to do with it.
In jQuery you can use relative positioning to select the item of interest. So, for example, if each item was followed by a favorite button, you can traverse the DOM from the clicked item to find the related item. You can then post this back via AJAX to store it an update the element as needed to reflect the updated status.
HTML (assumes you use styling to show the icon and favorite status)
<span class="normal" data-location="A">Location A</span> <span class="icon-favorite"></span>
JS
$('.favorite').click( function() {
var data = [],
newClass = 'favorite',
oldClass = 'normal',
$this = $(this),
$location = $(this).prev('span');
// if already favorited, reverse the sense of classes
// being applied
if ($location.hasClass('favorite')) {
newClass = 'normal';
oldClass = 'favorite';
}
data['location'] = $location.attr('data-location');
$.post('/toggle_favorite', data, function(result) {
if (result.Success) {
$location.removeClass(oldClass).addClass(newClass);
$this.removeClass('icon-'+newClass).addClass('icon-'+oldClass);
}
else {
alert('could not mark as favorite');
}
},'json');
});

Categories