How to insert Bootstrap drop-down values in database - javascript

i am using bootstrap for making a user form.
Now i need to insert selected drop-down value in database.
But i am facing two problems.
1) When i select any item from drop-down, it jumps to top of my screen in url because of href="#". When i removed "#", it started the page refresh on selection item.
2) How i target my drop-down list to insert any selected value in database using php.
My code is
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">Select City
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>Lahore</li>
<li>Islamabad</li>
<li>karachi</li>
</ul>
</div>
javascript code
$(document).ready(function() {
$(".dropdown-menu li a").click(function(){
$(this).parents(".dropdown").find('.btn').html($(this).text() + ' <span class="caret"></span>');
$(this).parents(".dropdown").find('.btn').val($(this).data('value'));
});

For the point 1 :
Since you have the # in the href the page scrolls up (i.e. navigating to the link target). You can prevent this event by adding event.preventDefault() in your code.
For Point 2: Since you said if you are able to get the value to your server side php code then you can proceed further you can make use of AJAX Post method. The final code would be
$(document).ready(function() {
$(".dropdown-menu li a").click(function(e){
e.preventDefault(); //this is the line which prevents the event
$(this).parents(".dropdown").find('.btn').html($(this).text() + ' <span class="caret"></span>');
$(this).parents(".dropdown").find('.btn').val($(this).data('value'));
//this is the code to post the value to server
$.post("YourPHPMethod.php",{name: $(this).text()} ,function(response){
alert("Response from server: "+response);
});
});

You have to post it to a php. I do it with ajax like this.
Look: http://www.codesheet.org/codesheet/wOHDXFju
function postContent(cv) {
$("#myDiv").html('L O A D I N G ...').show();
var url = "/post.php";
$.post(url, {id: cv} ,function(data) { //contentVar is the variable in post.php
$("#myDiv").html(data).show();
});
}

Related

Is there better way for following HTML Blade & jQuery scenario

I have a page with a response where a few items in a key named "tables" are coded as JQuery DataTable. My Goal is to do CRUD Operation on the same page index.blade.php by using Bootstrap Modal.
On clicking the EDIT button, I wanted to get clicked-row data in jQuery <script> and then fill it into the form inside a Modal.
As I've just started out with this as my first project, after two days long RnD on here and Google, I've figured out a way to do it. The next task I'm going to do is get & post requests via Ajax. But before that, I want to make sure if this is a good way or do I need a particular change/improvement.
Following is my script tag & HTML button:
<a href="javascript:void(0);" class="btn btn-sm text-primary btn-icon editButton"
data-bs-toggle="modal" data-bs-target="#editModal" data-id="{{ $table->id }}">
<i class="bx bx-edit-alt me-1"></i>
</a>
<script type="text/javascript">
$(document).ready(function() {
$('#myTable').DataTable();
var tables = #json($tables);
// Edit Function
$('.editButton').on('click', function() {
// Picking the clicked table from the response
var table;
for (let index = 0; index < tables.length; index++) {
if (tables[index].id == $(this).data("id")) {
table = tables[index];
break;
}
}
// Filling the Modal Form
$('#name').val(table.name);
$('#seats').val(table.seats);
$('#status').prop('checked', table.status);
$('#editForm').attr('action', '/tables/' + table.id);
// Focuses on the Name Field
$("#editModal").on('shown.bs.modal', function() {
$(this).find('#name').focus();
});
});
});
</script>

jQuery get clicked value in jinja2 loop

I have a small app with a flask backend and jinja2 templating.
In the html, I have a loop that organizes into batches creating 3 columns on the page:
{% for batch in df.iterrows() | batch(3) %}
<div class="row">
{% for row_id, row in batch %}
I have some jQuery to get the item that is clicked on in a cascading dropdown. A jinja2 loop is populating the dropdown by looping through a dataframe. The jQuery is getting the value from the html by ID (as the ul id):
<ul id="model1" class="list-group">
Ultimately I need three values, one for each batch. However, the code only returns the most recent item clicked on. The reason for that is I can't figure out how to get jQuery to get one item per batch -- or link to the batch somehow. Can I put the batch number in the ul id somehow?
$(document).ready(function(){
$('ul#menu li').hover(function(){
$(this).children('ul').delay(20).slideDown(200);
}, function(){
$(this).children('ul').delay(20).slideUp(200);
});
$('#model1 li').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('model1 ' + e.target.getAttribute('data-val'))
$("input[name=suggestion1]").val(e.target.getAttribute('data-val'));
});
//CODE is past here DOESN'T work but I left it in to give an idea
$('#model2 li').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('model2 ' + e.target.getAttribute('data-val'))
$("input[name=suggestion2]").val(e.target.getAttribute('data-val'));
});
$('#model3 li').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('model3 ' + e.target.getAttribute('data-val'))
$("input[name=suggestion3]").val(e.target.getAttribute('data-val'));
});
$("form").submit(function(){
var s1 = $("input[name=suggestion1]").val();
var s2 = $("input[name=suggestion2]").val();
var s3 = $("input[name=suggestion3]").val();
console.log(s1, s2, s3);
});
});
Posting this in case it helps someone else.
This excellent post explains how to use the loop variable in a flask template: count number of rows in flask templates
For my code, I made the div ID change based on the loop index.
{% for batch in recomm_df.iterrows() | batch(3) %}
<div class="row">
{% for row_id, row in batch %}
<div class="col-md-4" id="cat_{{loop.index}}">
Within that loop, I gave my unordered list an ID like :
<ul id="cat_sug" class="list-group">
Then you can grab those the data val that is clicked on in JQuery:
$('#cat_1 #cat_sug').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('cat_1 ' + e.target.getAttribute('data-val'))
// var s1 = e.target.getAttribute('data-val');
$("input[name=suggestion1]").val(e.target.getAttribute('data-val'));
});

How can I get ID from "ul" dynamic tag

I have the next situation.
I have a button in HTML code. When I press one of the options from the button I call a function that constructs the content from other button.
I have a ul tag in HTML code with a list of li tags inside. The value of this li tags are generated dynamically with a query database.
When I generate the options from li tags I assign a different ID to each other.
Here you can see the code that I have for the second button:
<div class="dropdown" class="btn-group-lg" id="test">
<button name="selSensor" id="seltipoSensor" class="btn btn-primary dropdown-
toggle" type="submit" data-toggle="dropdown">
<span>Select one option</span>
</button>
<ul class="dropdown-menu" id="test2">
</ul>
</div>
Here you can see the code that I have to generate the li tags inside the button.
<script type="text/javascript">
function selectedUbi(ubicacion){
var datos = {
"arg" : ubicacion
};
$.ajax({
data: datos,
url: 'condatabase/calculos_bdd2.php',
type: 'post',
success: function (response) {
if(response){
document.getElementById("test2").innerHTML = "";
var ul = document.getElementById("test2");
for (i=0;i<response.length;i++){
var li = document.createElement("li");
li.appendChild(document.createTextNode(response[i][i+1]));
li.setAttribute("id", "element"+i);
li.setAttribute("onclick",myFunction);
ul.appendChild(li);
}
}
},
dataType:"json"
});
}
</script>
The question that I have is...
how can I get the ID from the li tag that I generate dynamically?
I tried to use "getElementByID" and "getElementByTagName" but as the ID is dynamic I have no idea to caught the value.
For example the button have the next options to select:
- apple (ID= element0)
- bannana (ID= element1)
- carrot (ID= element2)
When I select the option "bannana" I need to get the ID "element1".
You can use querySelectorAll on your container to get a list of elements and then read their attribute id.
function getIds(container){
return [...container.querySelectorAll('li[id]')].map(li => li.getAttribute('id'));
}
However, I would rather recommend to create a data layer abstraction to handle operations related to data fetching, etc... in order to avoid a strong coupling on your html structure and your "logic" code.
function createStore(){
return {
async fetch(arg){ /*... return your data (and cache it etc */ }
};
}
so your button handlers can share that "store"
const store = createStore();
document.getElementBy('button1').addEventListener('click', () => {
store.fetch().then(data => { /* do something with your data like updating html ... */})
});
document.getElementBy('button2').addEventListener('click', () => {
store.fetch().then(data => { /* do something with your data like updating html ... */})
});
//etc

Dynamic attribute value element locator in Protractor

When I add a new button with some value it gets dynamically added into DOM. Non-Angular HTML element for this button is:
<li class="ui-state-default droppable ui-sortable-handle" id="element_98" data-value="2519">
25.19 EUR
<button type="button" class="btn btn-default removeParent">
<span class="glyphicon glyphicon-remove" aria-hidden="true">
</span>
</button>
</li>
Once I remove this button I want to check it is not present anymore. Element that I'm searching for is data-value="2519"and this could be anything I set, like for example 2000, 1000, 500, 1050,...
In page object file I have tried to use the following:
this.newValueButtonIsNotPresent = function(item) {
newValueButton = browser.element(by.id("containerQUICK_ADD_POINTS")).all(by.css('[data-value="' + item + '"]'));
return newValueButton.not.isPresent();
};
And in spec file I call this function as follows:
var twentyEurosButtonAttributeValue = '2000';
describe("....
it ("...
expect(predefined.newValueButtonIsNotPresent(twentyEurosButtonAttributeValue)).toBeTruthy();
I know this is not correct, but how I can achieve something like that or is there another way?
Stupid me, I found a simple solution. Instead dynamically locating an element I located the first on the list, which is always the one, which was newly added and then checked if it's text does not match:
Page object file:
this.newValueButtonIsNotPresent = function() {
newValueButton = browser.element(by.id("containerQUICK_ADD_POINTS")).all(by.tagName('li')).first();
return newValueButton.getText();
};
Spec file:
// verify element 20.00 EUR is not present
predefined.newValueButtonIsNotPresent().then(function(value) {
expect(value).not.toEqual(twentyEurosText);
});

Update dynamically generated list item (generated using PHP) after ajax call

The following HTML code is being echoed using a while loop in PHP which is adding a list item after fetching data from database.
PHP:
echo '
<li>
<div class="collapsible-header">
<div class = "left">
<div class = "issueStatusIcon" style = "background-color:'.$smallCircleColor.';">'.$smallMsg.'</div>
<span class = "issueTitle" style = "font-family: robotoBold">'.$issueTitle.'</span>
</div>
<div class = "issueButtonsGroup">
<form id = "archiveIssueForm'.$i.'" issue-name = "'.$issueTitle.'" action = "archiveIssue.php">
<input type = "hidden" value = "'.$issueID.'" name = "issueID"/>
</form>
<a class = "right archiveIconButton" onclick = "ajaxIssueArchive('.$i.')" href = "#">
<i class="material-icons black-text issueOptions archiveIcon">archive</i>
</a>
<a class = "right"><i class="material-icons black-text issueOptions">edit</i></a>
</div>
</div>
</li>
';
This is the preview image of the generated list:
Notice the cursor over the archive button which archives the list item. The class for that button is archiveIconButton (you can find it in the above code). When the button is clicked, archiveIssueForm is submitted via AJAX (each form has a unique identifier variable $i appended to its id).
Following is the JQuery AJAX code:
JQuery:
<script>
function ajaxIssueArchive($num){
$.ajax({
type: "post",
url: "archiveIssue.php",
data: $('#archiveIssueForm' + $num).serialize(),
success: function(data){
$fetchIssueName = $('#archiveIssueForm' + $num).attr("issue-name");
$toastText = $fetchIssueName + " has been archived";
Materialize.toast($toastText, 3000);
$('#archiveIssueForm' + $num).html(data);
}
});
}
</script>
After archiving any list item, it gets deleted from the database. I want to update the ul element which contains these list items so that the list item which gets deleted doesn't gets displayed after the AJAX form submission.
Assume the id of ul to be issueListUL.
What i'm currently getting is the whole code of the html page displayed in the li item. I am certainly doing something wrong, any help would be appreciated!
After archiving a list item:
I was able to solve this issue in the following way, The JQuery script in the question should be changed like this:
JQuery:
<script>
function ajaxIssueArchive($num){
$.ajax({
type: "post",
url: "archiveIssue.php",
data: $('#archiveIssueForm' + $num).serialize(),
success: function(data){
//assigning the updated ul's html to a variable
$afterIssueArchival = $(data).find("#issueListContainer").html();
//toast
$fetchIssueName = $('#archiveIssueForm' + $num).attr("issue-name");
$toastText = $fetchIssueName + " has been archived";
Materialize.toast($toastText, 3000);
//updation of ul's html, ID of the ul which contains all the list items is assumed to be 'listContainer'
$("#issueListContainer").html($afterIssueArchival);
}
});
}
</script>
When updating an element's html, just extract the element's updated html code from data attribute in the ajax code (as show in the above code) and update the existing element's html with it!
Hope this helps people with the same problem as mine! :D

Categories